ホームページ  >  記事  >  バックエンド開発  >  Go のバッファー チャネルのブロック メカニズム

Go のバッファー チャネルのブロック メカニズム

WBOY
WBOY転載
2024-02-10 14:30:111026ブラウズ

Go 的 Buffered Channel 的阻塞机制

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 サイトの他の関連記事を参照してください。

声明:
この記事はstackoverflow.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。