ホームページ  >  記事  >  バックエンド開発  >  golang がチャネルを閉じてもレシーバーの goroutine はブロックしません

golang がチャネルを閉じてもレシーバーの goroutine はブロックしません

王林
王林転載
2024-02-06 08:25:071138ブラウズ

golang がチャネルを閉じてもレシーバーの goroutine はブロックしません

質問の内容

以下に示すように、go チャネルを学習するためのコードをいくつか書きました。 リーリー

close() 関数をコメントアウトすると、「すべての goroutine はスリープ - デッドロック!」というエラーが表示されるため、「for」ステートメントはブロックされますが、これは合理的だと思われます。

close() のコメントを解除しても、「for」ステートメントは停止しません。受信者はチャネルからデフォルト値 0 と nil を取得し、決してブロックしません。

チャネルに何も送信せず、チャネルを定義した後に

close() を呼び出しているにもかかわらずです。受信機がブロックしたり、エラーを引き起こしたりすることはありません。

close 関数が何をするのか混乱していますが、この関数は特定の種類のデフォルト値をチャネルに送信する go ルーチンを開始し、決して停止しないのでしょうか?


正解


チャンネルが閉じられても読むことはできますが、

okはfalseになります。だからこそ、あなたの for は決して止まらないのです。また、条件 if !ok {break } を使用して for ステートメントを中断する必要があります。

チャネルが閉じられていない場合、チャネルからデータを読み取ろうとすると、バッファリングされたチャネルかバッファリングされていないチャネルに応じてブロックされるかどうかが決まります。

バッファ チャネル: サイズを指定します (

make(chan int, 1))。 バッファリングされていないチャネル: サイズを指定しませんでした (
make(chan int))

コメント

close の場合、intchan と strchan データをチャネルに送信します。したがって、コンソールには次の結果が表示されます。 リーリー

ただし、これ以降、両方のバッファ チャネルにデータがなくなりました。その後、それを読み取ろうとすると、バッファリングされたチャネルにデータがないためブロックされます。 (実際、データがない場合もバッファリングは行われません。)

その後、メインの goroutine がチャネルからのデータの待機中にブロックされているため、

all goroutine are sleep - Deadlock が表示されます。ちなみに、このプログラムを実行すると、コードを実行するためのメイン goroutine が開始されます。メインの goroutine が 1 つだけブロックされている場合、コードの実行を手伝ってくれる人が誰もいないことを意味します。

for ステートメントの前に次のコードを追加できます。

リーリー

コードを実行する「可能性がある」ゴルーチンがまだ存在するため、デッドロックが発生していないことがわかります。

以上がgolang がチャネルを閉じてもレシーバーの goroutine はブロックしませんの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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