gpt4 book ai didi

goroutine 只通过 channel 传递一半的值

转载 作者:数据小太阳 更新时间:2023-10-29 03:06:43 25 4
gpt4 key购买 nike

我有一个文件:

package main
import "fmt"

func
combinations(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;
}
}
}

func
main() {
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 个字节的所有可能组合,IE:

0000
0100
...
0001
...
0505

但是,它似乎跳过所有其他值,并打印相同的值两次,IE:

0100
0100
0300
0300
...

为什么要这样做?我在“结果 <- res”行之前插入了打印件,这些都是正确的。

最佳答案

如果我们稍微简化一下,Go 中的 slice 基本上是一个指向数组的指针,因此通过 channel 传递您仍然拥有并修改的 slice ,就会造成数据竞争。

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

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

您的情况的解决方案是在通过 channel 发送之前复制 slice :

buf := make([]byte, len(res))
copy(buf, res)
result <- buf

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

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

关于goroutine 只通过 channel 传递一半的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33020521/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com