ホームページ >バックエンド開発 >Golang >特定のゴルーチンで Go `select` ステートメントを終了するには、なぜ `fmt.Print()` が必要なのでしょうか?

特定のゴルーチンで Go `select` ステートメントを終了するには、なぜ `fmt.Print()` が必要なのでしょうか?

Susan Sarandon
Susan Sarandonオリジナル
2024-11-26 05:40:10830ブラウズ

Why Does a Go `select` Statement Need `fmt.Print()` to Terminate in a Specific Goroutine?

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

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。