给出以下示例:http://play.golang.org/p/owvJ8Oi77S
func produce(dataChannel chan int) {
for i := 0; i < 10; i++ {
dataChannel <- i
}
}
func main() {
dataChannel := make(chan int)
go produce(dataChannel)
go produce(dataChannel)
go produce(dataChannel)
for i := 0; i < 30; i++ {
data := <-dataChannel
fmt.Printf("%v ", data)
}
}
Run Code Online (Sandbox Code Playgroud)
我的假设是从多个go例程写入一个通道是不安全的吗?
是否有一种通用/惯用的方法可以安全地完成这项工作?我知道你可以为每个生成数据的例程创建一个单独的通道,我只是想知道这是否是最干净的解决方案还是有其他替代方案.
通道旨在在线程之间共享(这是"线程安全"的正常含义).使用频道意味着您没有共享内存,您可能会面临种族危险.所以丹尼尔的答案是正确的:使用渠道,因为这就是他们的目的.
但请注意,goroutines创建了通信顺序进程的网络,如果存在设计错误,有时会死锁.他们也可以活锁(同样的事情,但忙碌).
关于如何避免死锁/活锁,有相当多的知识.其中很大一部分来自奥卡姆在80年代和90年代流行的日子.Jeremy Martin(无死锁并发系统的设计策略),Peter Welch(高级范例)等人都有一些特殊的宝石.