Skip to content

Commit

Permalink
尝试使用管道控制协程的执行顺序,尝试使用管道进行限流
Browse files Browse the repository at this point in the history
  • Loading branch information
peifengll committed May 22, 2024
1 parent 894157e commit 00a7ec7
Show file tree
Hide file tree
Showing 5 changed files with 288 additions and 0 deletions.
35 changes: 35 additions & 0 deletions channel_/cc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package channel_

import (
"fmt"
"testing"
)

func TestSolve1_1(t *testing.T) {
solve1_1()
}

func TestSolve1_2(t *testing.T) {
solve1_2()
}

func TestSolve2_1(t *testing.T) {
solve2_1()
}

// 测试 长度为n的管道的大小
// 结论: len输出的是管道队列里边现在有几个待读取
func TestLenChannel(t *testing.T) {
ch := make(chan int, 7)
ch <- 2
ch <- 2
ch <- 2
fmt.Println(len(ch))
}

/*
=== RUN TestLenChannel
3
--- PASS: TestLenChannel (0.00s)
PASS
*/
65 changes: 65 additions & 0 deletions channel_/question.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package channel_

import "fmt"

// 问题 1
// 四个协程,每个协程都有自己的编号 ,要求按顺序打印编号并且一直循环

func solve1_1() {
// id 是编号
goprint := func(out <-chan struct{}, in chan<- struct{}, id int) {
nu := struct {
}{}
for {
<-out
fmt.Println(id)
in <- nu
}
}
// 初始化四个协程,每个都要等前边的就可以了
a, b, c, d := make(chan struct{}), make(chan struct{}), make(chan struct{}), make(chan struct{})
// 四个协程,每个收到了上一个发送的信息 ,就可以了
go goprint(a, b, 1)
go goprint(b, c, 2)
go goprint(c, d, 3)
go goprint(d, a, 4)
a <- struct{}{}
select {}
}

func solve1_2() {
ch := make([]chan struct{}, 4) // 初始化四个
for i := 0; i < 4; i++ {
ch[i] = make(chan struct{})
}
for i := 0; i <= 3; i++ {
go func(k int) {
for {
<-ch[k-1]
fmt.Println(k)
ch[k%4] <- struct{}{}
}
}(i + 1)
}
ch[0] <- struct{}{}
select {}
}

// 问题2 用channel 实现一个限流器
func solve2_1() {
// 限流器,就限制访问,每次只允许n个人访问,然后就去竞争呗
// 就争着去放,能放进去,自然就是竞争到了
ctrl := make(chan struct{}, 3)
// 十个人去争夺
for i := 1; i <= 10; i++ {
go func(k int) {
for {
ctrl <- struct{}{}
// 拿到了,打印一哈
fmt.Println(k, "号拿到了")
<-ctrl
}
}(i)
}
select {}
}
54 changes: 54 additions & 0 deletions channel_/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# 问题1 四个协程,每个协程都有自己的编号 ,要求按顺序打印编号并且一直循环

```go

func solve1_1() {
// id 是编号
goprint := func(out <-chan struct{}, in chan<- struct{}, id int) {
nu := struct {
}{}
for {
<-out
fmt.Println(id)
in <- nu
}
}
// 初始化四个协程,每个都要等前边的就可以了
a, b, c, d := make(chan struct{}), make(chan struct{}), make(chan struct{}), make(chan struct{})
// 四个协程,每个收到了上一个发送的信息 ,就可以了
go goprint(a, b, 1)
go goprint(b, c, 2)
go goprint(c, d, 3)
go goprint(d, a, 4)
a <- struct{}{}
select {}
}

func solve1_2() {
ch := make([]chan struct{}, 4) // 初始化四个
for i := 0; i < 4; i++ {
ch[i] = make(chan struct{})
}
for i := 0; i <= 3; i++ {
go func(k int) {
for {
<-ch[k-1]
fmt.Println(k)
ch[k%4] <- struct{}{}
}
}(i + 1)
}
ch[0] <- struct{}{}
select {}
}

```



# 问题2 用channel 实现一个限流器


```go

```
40 changes: 40 additions & 0 deletions test_goredis/hash_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package main

import (
"context"
"log"
"strconv"
"testing"
)

func TestShouldBind(t *testing.T) {
r := NewRedis()
ctx := context.Background()
key := "space_repeat_BLNOXd36vf_rate"
res, err := r.HGetAll(ctx, key).Result()

if err != nil {
log.Fatalln(err)
}
log.Println(res)

}

func TestLoadParm(t *testing.T) {
r := NewRedis()
ctx := context.Background()
key := "test_dic_parm"
r.HSet(ctx, key,
"max_interval", 362,
//"weights", "0.4, 0.6, 2.4, 5.8, 4.93, 0.94, 0.86, 0.01, 1.49, 0.14, 0.94, 2.18, 0.05, 0.34, 1.26, 0.29, 2.61",
"request_retention", 0.9)
dic := r.HGetAll(ctx, key).Val()
log.Println(dic)
float1, err := strconv.ParseFloat(dic["max_interval"], 10)
if err != nil {
log.Fatalln(err)
}

RequestRetention, err := strconv.ParseFloat(dic["request_retention"], 10)
log.Println(float1, RequestRetention)
}
94 changes: 94 additions & 0 deletions test_goredis/set_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package main

import (
"context"
"testing"
)

const setKey = "i_am_z_set"

func TestAdd(t *testing.T) {
r := NewRedis()
ctx := context.Background()
r.SAdd(ctx, setKey, 99)
r.SAdd(ctx, setKey, 98)
}

func TestRem(t *testing.T) {
r := NewRedis()
ctx := context.Background()
// 移除目标元素
r.SRem(ctx, setKey, 98)
}

/*
func GetRedisClient() *redis.Client {
return redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
}
// redisSetTest Set集合(无序不重复)
func redisSetTest(cli *redis.Client) {
// SAdd:添加(可一次添加多个)
cli.SAdd("city", "西二旗", "东京", "纽约", "首尔", "新德里")
// SRem:移除(可一次移除多个)
cli.SRem("city", "东京", "首尔")
//SMembers:查看set中的全部信息
fmt.Println(cli.SMembers("city").Val()) // [新德里 纽约 西二旗]
// 判断set中是否存在某个值
fmt.Println(cli.SIsMember("city", "北京").Val()) //false
//随机获取set集合中的一个元素
fmt.Println(cli.SRandMember("city").Val()) //西二旗
//随机获取指定个数的元素
fmt.Println(cli.SRandMemberN("city", 2).Val()) //[新德里 西二旗]
cli.SAdd("city", "莫斯科", "平襄", "雅加达", "马尼拉")
fmt.Println(cli.SMembers("city").Val()) //[莫斯科 马尼拉 纽约 新德里 西二旗 平襄 雅加达]
//随机删除一条数据
cli.SPop("city")
fmt.Println(cli.SMembers("city").Val()) //[莫斯科 纽约 马尼拉 平襄 雅加达 新德里]
//随机删除指定条数数据
cli.SPopN("city", 3)
fmt.Println(cli.SMembers("city")) // [马尼拉 纽约 平襄]
//将指定的值移动到指定集合(指定集合不存在则创建)
b, err := cli.SMove("city", "language", "纽约").Result()
if err != nil {
panic(err)
}
fmt.Println(b) //true
fmt.Println(cli.SMembers("city").Val()) //[马尼拉 平襄]
fmt.Println(cli.SMembers("language").Val()) //[纽约]
//数字集合类
cli.SAdd("set1","a","b","c","d")
cli.SAdd("set2","a","c","e","f")
//差集(注意以谁为基准,也就是第一个参数是谁!!!)
fmt.Println(cli.SDiff("set1","set2").Val()) //[b d]
fmt.Println(cli.SDiff("set2","set1").Val()) //[e f]
//交集
fmt.Println(cli.SInter("set1","set2").Val())//[a c]
//并集
fmt.Println(cli.SUnion("set1","set2").Val())//[c a b f d e]
}
func main() {
rdb := GetRedisClient()
defer rdb.Close()
pong := rdb.Ping().Val()
fmt.Printf("数据连接状态:%v\n", pong) // 数据连接状态:PONG
redisSetTest(rdb)
}
*/

0 comments on commit 00a7ec7

Please sign in to comment.