英文:
Thread-safe way to funnel data from multiple go routines
问题
给定以下示例: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)
}
}
我假设从多个Go协程向一个通道写入是不安全的,这个假设正确吗?
有没有一种常见/惯用的方法可以安全地实现这个?我知道可以为每个产生数据的协程创建一个单独的通道,我只是想知道这是否是最清晰的解决方案,或者是否还有其他选择。
英文:
Given the following example: 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)
}
}
Is my assumption that writing to a channel from multiple go routines unsafe correct?
Is there a common/idiomatic way to do this safely? I know you can make a separate channel for each routine that's producing data, I was just wondering if that was the cleanest solution or if there are other alternatives.
答案1
得分: 41
通道是完全线程安全的。它们是在 goroutine 之间进行通信的官方方式。我对你的代码没有任何问题。这就是 Go 的美妙之处。
英文:
Channels are completely thread safe. They are the official way to communicate between goroutines. I see nothing wrong with your code. This is the beauty of Go.
答案2
得分: 9
通道旨在在线程之间共享(这是“线程安全”的正常含义)。使用通道意味着您没有共享内存,也就没有了可能出现的竞争危险。所以丹尼尔的回答是正确的:使用通道,因为这就是它们的用途。
但请注意,goroutine 创建了一组通信的顺序进程网络,如果设计有误,有时可能会发生死锁。它们也可能会发生活锁(与死锁类似,但是一直在忙碌)。
有很多关于如何避免死锁/活锁的知识。其中很多来自于Occam 在80年代和90年代流行的时候。有一些特别有价值的论文,如Jeremy Martin的《无死锁并发系统的设计策略》、Peter Welch的《更高级的范式》等。
英文:
Channels are intended to be shared between threads (and this is the normal meaning of "being thread-safe"). Using channels means you DON'T have shared memory, with the race hazards that you would risk. So Daniel's answer is correct: use channels because that's what they're for.
But note that goroutines create networks of communicating sequential processes that can sometimes deadlock if there's a design mistake. They can also livelock (same thing but being busy).
There is a considerable body of knowledge on how to avoid deadlock/livelock. Much of it is from the days when Occam was popular in the '80s and '90s. There are a few special gems from people such as Jeremy Martin (Design Strategy for Deadlock-Free
Concurrent Systems), Peter Welch (Higher Level Paradigms) and others.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论