select を使用した goroute Does Not Terminate Without fmt.Print()
Go Tour 演習 #71 の select ステートメントを使用した gorouteデフォルトの場合に fmt.Print() ステートメントが追加されない限り、継続的に実行されます。この動作は、デフォルト ステートメントが存在する場合に select の操作が変更されたために発生します。
デフォルトがない場合、select は監視されているチャネルのいずれかでメッセージが受信されるまでブロックします。デフォルトを追加すると、どのチャネルにもメッセージがない場合、select はデフォルトの分岐を実行します。
元のコードでは、default ステートメントは無限ループを作成します。
for { select { case todo := <-toDoList: ... case <-doneCrawling: ... default: if os.Args[1] == "ok" { fmt.Print("") } if crawling == 0 { goto END } } }
fmt なし。デフォルト内で Print() を使用すると、スケジューラは他のゴルーチンをスケジュールできず、デッドロックが発生します。 fmt.Print() を追加すると、スケジューラが通常の機能を継続できるようになり、ゴルーチンを完了できるようになります。
非ブロッキング選択を使用するようにコードを変更すると、問題が解決されます。
for { select { case todo := <-toDoList: ... case <-doneCrawling: ... } if crawling == 0 { break } }
または、GOMAXPROCS=2 を設定して元のコードを動作させることもできます。これは、過負荷になったスケジューラの問題を示します。
以上が特定のゴルーチンで Go `select` ステートメントを終了するには、なぜ `fmt.Print()` が必要なのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。