Go 言語には、バッファー チャネルと呼ばれる特別なチャネル タイプがあり、チャネル内に一定数の要素を保存します。チャネル内の要素の数が設定された上限に達すると、他のコルーチンがチャネルから要素を読み取るまで、書き込み操作はブロックされます。逆に、チャネル内の要素の数がゼロの場合、別のコルーチンがチャネルに要素を書き込むまで、読み取り操作もブロックされます。このブロック メカニズムにより、コルーチン間の同期と通信を効果的に制御できます。この記事では、Go言語におけるBuffered Channelのブロックの仕組みを詳しく紹介します。
「Tour of Go」では、サンプルコードは次のようになります。 リーリー
正常に実行され、印刷されますリーリー
この動作は、次のようなこの演習の説明とは異なります。 リーリーch <- 2
行以降、ch は満杯であり、メインのゴルーチンである別個のゴルーチンを 1 つだけ実行しているため、このゴルーチンは ## までブロックされる必要があります。 #ch
は受信側によって消費されるため、コードは fmt.Println(<-ch)
行には到達せず、 のような内容になるはずです。
リーリー
しかし、そうではないため、混乱しており、指導を求めています。
これは私が書いた別のコードです
実行結果は
リーリーこれはさらに混乱を招きます。今回は、送信を行う別の goroutine があります。私の予想では、最初の
fmt.Println(<-chh)の間にメインの goroutine がブロックされるはずです。スケジューラは匿名関数を実行するゴルーチンを選択し、
chh まで実行する必要があります。その後、スケジューラ自体がブロックされ、スケジューラは再びメインのゴルーチンに戻ります。ただし、結果が示すように、2 番目のゴルーチンはchh の直後でブロックされます。なぜこうなった? <code>
######編集###:
そもそも、なぜローカルで 1 が表示されるのか、まだわかりません。リモートサーバーで go Playground を使用しようとすると、異なる動作が表示されますが、現在は期待どおりです。
チャネルは 3 つのキュー (ゴルーチンの受信、ゴルーチンの送信、値バッファ) で構成されていることが知られています。匿名関数が実行されているとき、チャネル
chh のステータスは (送信中:空、値バッファ: 空、受信:[メイン] )。
実行中の子ゴルーチンは、値を実際に値バッファに渡すことなく、メインのゴルーチンに直接プッシュするだけです。そのため、chh を押した後の
1 の長さは
0
解決策
この通路は 2 人が収容できます。 2 回の送信はブロックされずに成功する可能性があります。
3 つ目は できません。送信は、送信前にチャネル
以上がGo のバッファー チャネルのブロック メカニズムの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。