ホームページ >バックエンド開発 >Golang >Infinite Go ルーチンが他の Go ルーチンのチャネルへの送信をブロックするのはなぜですか?

Infinite Go ルーチンが他の Go ルーチンのチャネルへの送信をブロックするのはなぜですか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-04 16:52:11556ブラウズ

Why Does an Infinite Go Routine Block Other Goroutines from Sending to Channels?

他のブロックをブロックする Go ルーチン: 詳しい説明

Go では、次のコードは、無限ループを持つ goroutine のように見える異常な動作を示します。別のゴルーチンのメッセージが意図したメッセージに到達するのを防ぎます。 channel:

func main() {
   timeout := make(chan int)
   go func() {
      time.Sleep(time.Second)
      timeout <- 1
    }()

    res := make(chan int)
    go func() {
        for {
        }
        res <- 1
    }()
    select {
        case <-timeout:
            fmt.Println("timeout")
        case <-res:
            fmt.Println("res")
    }
}

プログラムは 1 秒後に終了するのではなく、無限ループに入ります。なぜこのようなことが起こるのでしょうか?

Go の協調スケジューリングを理解する

その答えは、Go がゴルーチンに対して協調スケジューリングを使用していることにあります。ゴルーチンは、次のような特定の条件下でスケジューラに制御を渡します。

  • バッファなしチャネル送受信操作
  • システム コール (ファイル/ネットワーク I/O など)
  • メモリ割り当て
  • time.Sleep()最初の goroutine の無限ループは決して放棄されないため、他の goroutine が実行され、チャネルにメッセージが送信されなくなります。これには、決して到着しないメッセージを待機するタイムアウト チャネルが含まれます。
  • 考えられる解決策

協調的なスケジューリングはこのような状況につながる可能性がありますが、考えられる解決策はあります。 :

GOMAXPROCS の増加:

この環境変数を使用すると、複数のスレッドがゴルーチンを同時に実行できるようになり、1 つのゴルーチンが他のゴルーチンをブロックする可能性が減ります。

  • プリエンプティブ スケジューラの使用 (将来の目標): Go 言語開発者は、プリエンプティブ スケジューラの実装を目指しています。ゴルーチン間を強制的に切り替えて、 block.
  • 手動譲り: runtime.Gosched() 関数を使用すると、ゴルーチンが手動で制御をスケジューラに譲り、他のゴルーチンをブロックする可能性のある無限ループから抜け出すことができます。

以上がInfinite Go ルーチンが他の Go ルーチンのチャネルへの送信をブロックするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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