すべてのチャネルが閉じているときの Select ステートメントの中断
複数のゴルーチンが個々のチャネルにデータを送信するシナリオを考えてみましょう。このデータを任意の順序で消費します。 select ステートメントを使用すると、複数のソースからの同時入力を処理する便利な方法が提供されます。ただし、すべてのチャネルが閉じている場合にのみループを終了する必要がある場合に問題が発生します。
単純な解決策
直感的なアプローチには、各チャネルの可用性を確認することが含まれる場合があります。 ok フラグを使用します。ただし、この解決策では、閉じられたチャネルが選択されると再び使用可能になるため、エラーが発生しやすくなります。これは、このプレイグラウンドの例で示されているように、無限ループにつながります: http://play.golang.org/p/rOjdvnji49.
改善された解決策
詳細効果的なアプローチは、nil チャネルが通信の準備ができていないという事実を利用することです。チャネルが閉じるたびに、チャネルを nil に設定して、将来の select ステートメントから確実に除外することができます。これにより、すべてのチャネルが閉じた場合にのみループが終了することが保証されます:
for { select { case x, ok := <-ch: fmt.Println("ch1", x, ok) if !ok { ch = nil } case x, ok := <-ch2: fmt.Println("ch2", x, ok) if !ok { ch2 = nil } } if ch == nil && ch2 == nil { break } }
プレイグラウンドの例: http://play.golang.org/p/8lkV_Hffyj
実用的な考慮事項
実際には、単一の select ステートメントで多数のチャネルを処理する必要があることはほとんどありません。このようなシナリオが発生した場合は、過剰な nil チェックでコードが乱雑になるのを避けるために、チャネル マルチプレクサーなどのより特殊なソリューションを使用することをお勧めします。
以上がGo ですべてのチャネルが閉じているときに select ステートメントから抜け出すにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。