为了账号安全,请及时绑定邮箱和手机立即绑定

goroutine 只通过通道传递一半的值

goroutine 只通过通道传递一半的值

Go
哈士奇WWW 2021-11-15 15:36:07
我有一个文件:package mainimport "fmt"funccombinations(result chan []byte, len int, min byte, max byte) {    res := make([]byte,len)    for i := 0; i < len; i++ {        res[i] = min    }    result <- res    for true {        i := 0        for i = 0; i < len; i++ {            if res[i] < max {                res[i] = res[i] + 1;                break            } else {                res[i] = 32            }        }        result <- res        if(i == len) {            close(result)            return;        }    }}funcmain() {    combination_chan := make(chan []byte)    go combinations(combination_chan, 2, 0, 5)    for next_combination := range combination_chan {        fmt.Printf("%x\n",next_combination)    }}我希望这会打印 0 到 5 之间 2 个字节的所有可能组合,即:00000100...0001...0505但是,它似乎跳过所有其他值,并打印两次相同的值,IE:0100010003000300...为什么会这样做?我在“result <- res”行之前插入了打印件,这些都是正确的。
查看完整描述

1 回答

?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

如果我们稍微简化一下,Go 中的切片基本上是一个指向数组的指针,因此通过传递一个您仍然拥有和修改的切片通过通道,您会创建数据竞争。


不知道切片的内容在传递到通道的那一刻和另一个 goroutine 从通道读取的那一刻之间是否被修改。


所以你的整个算法会导致未定义的行为,因为你只是在修改它们时一遍又一遍地传递相同的内容。


您的情况的解决方案是在通过通道发送之前复制切片:


buf := make([]byte, len(res))

copy(buf, res)

result <- buf

看到它在这里运行:http : //play.golang.org/p/ulLYy9Uqnp


另外,我不建议使用len作为变量名,因为它可能与len()内置函数冲突。


查看完整回答
反对 回复 2021-11-15
  • 1 回答
  • 0 关注
  • 180 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信