21

次の例を考える: 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 ルーチンからチャネルへの書き込みが安全ではないという私の仮定は正しいですか?

これを安全に行うための一般的/慣用的な方法はありますか? データを生成するルーチンごとに個別のチャネルを作成できることは知っていますが、それが最もクリーンなソリューションなのか、それとも他の方法があるのか​​ 疑問に思っていました.

4

2 に答える 2

39

チャネルは完全にスレッドセーフです。それらは、ゴルーチン間で通信するための公式の方法です。あなたのコードには何の問題もありません。これが囲碁の美しさです。

于 2012-12-03T20:04:02.997 に答える
8

チャネルは、スレッド間で共有されることを意図しています (これは、「スレッドセーフであること」の通常の意味です)。チャネルを使用するということは、メモリを共有しないことを意味し、競合の危険を冒す可能性があります。したがって、ダニエルの答えは正しいです。チャネルを使用するのは、それが目的だからです。

ただし、ゴルーチンは、設計ミスがあるとデッドロックすることがある一連のプロセスを通信するネットワークを作成することに注意してください。彼らはライブロックすることもできます(同じことですが、忙しいです)。

デッドロック/ライブロックを回避する方法については、かなりの知識があります。その多くは、80 年代と 90 年代にオッカムが人気だった時代のものです。Jeremy Martin ( Design Strategy for Deadlock-Free Concurrent Systems ) や Peter Welch ( Higher Level Paradigms )などの人々からの特別な逸品がいくつかあります。

于 2012-12-04T20:55:24.013 に答える