注:この質問では、2 つのバージョンのコードを比較し、異なる出力が生成される理由を理解しようとしています。play.golang.orgの 2 つのバージョンの実行例へのリンクは、FIG1とFIG2です。
私は、Rob Pike が Google I/O 2012 で発表したGo Concurrency Patternsスライドに取り組んでいますが、シーケンスの例は少しわかりにくいです。スライド 29に、多重化後にシーケンスを復元する方法の例があります。つまり、複数のチャネルからのメッセージが 1 つのチャネルに多重化され、各メッセージ構造は「waitForIt」と呼ばれるチャネルを共有します。このチャネルは、メッセージを提供するサービス (参照されている例では退屈なサービス) とサービスのクライアントが順番に並んでいることを確認するためのものです。ABABAB の順序付けを行うために、クライアントが waitForIt チャネルを介して2 つの待機を送信する必要がある理由がわかりません。
図1
for i := 0; i < 10; i++ {
msg1 := <-c
fmt.Printf("%s\n", msg1.str)
msg2 := <-c
fmt.Printf("%s\n", msg2.str)
msg1.wait <- true
msg2.wait <- true /* why is this second wait necessary? */
}
Message 構造体が同じチャネルを共有している場合、なぜ 2 つの待機が必要なのですか? 単一の<-wait では十分ではありません。
図2
for i := 0; i < 10; i++ {
msg1 := <-c
fmt.Printf("%s\n", msg1.str)
msg2 := <-c
fmt.Printf("%s\n", msg2.str)
msg1.wait <- true
}
ただし、単一の待機が使用されると、メッセージ 1 が出力の先頭で 2 回繰り返され、その後シーケンス ABAB... が続くため、出力は次のようになります。
Message 1: Iteration 0
Message 2: Iteration 0
Message 1: Iteration 1 // Message 1 is repeated twice
Message 1: Iteration 2 // Here's the repetition
Message 2: Iteration 1
Message 1: Iteration 3
Message 2: Iteration 2
Message 1: Iteration 4
Message 2: Iteration 3
Message 1: Iteration 5
FIG1のように、 wait変数に2 つの送信がある場合、シーケンスは最初から ABAB... になります。
Message 1: Iteration 0
Message 2: Iteration 0
Message 1: Iteration 1
Message 2: Iteration 1
Message 1: Iteration 2
Message 2: Iteration 2
Message 1: Iteration 3
Message 2: Iteration 3
Message 1: Iteration 4
Message 2: Iteration 4
正しいシーケンスのために同じチャネルで2 番目の待機状態への送信が必要なのはなぜですか?