猿问

从多个go例程中收集数据的线程安全方法

给出以下示例: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例程写入通道不安全是正确的吗?


是否有安全的常用/惯用方式?我知道您可以为每个生成数据的例程创建一个单独的通道,我只是想知道这是否是最干净的解决方案,或者是否还有其他选择。


狐的传说
浏览 194回答 2
2回答

犯罪嫌疑人X

通道是完全线程安全的。它们是goroutine之间进行交流的官方方式。我认为您的代码没有错。这就是Go的美。

米琪卡哇伊

通道旨在在线程之间共享(这是“线程安全”的通常含义)。使用频道意味着您没有共享的内存,而您可能会冒着种族危险。因此,丹尼尔(Daniel)的答案是正确的:使用渠道,因为这就是他们的目的。但是请注意,goroutine创建了通信顺序过程的网络,如果存在设计错误,有时可能会死锁。他们还可以进行活锁(同样的事情,但是很忙)。有很多有关如何避免死锁/活锁的知识。这很大程度上是从Occam在80年代和90年代流行的时代开始的。诸如Jeremy Martin(无死锁并发系统的设计策略),Peter Welch(高级范例)等人提供了一些特殊的宝石。
随时随地看视频慕课网APP

相关分类

Go
我要回答