無限ループ Goroutine が Go HTTP サーバーをブロック
同時実行の管理を担当する Go ランタイムは、ノンブロッキング操作に誇りを持っています。ただし、HTTP サーバー内から開始される無限ループのゴルーチンを含むシナリオでは懸念が生じます。 (runtime.GOMAXPROCS によると) 十分なスレッドとゴルーチンがあるにもかかわらず、この無限ループはサーバーによる他のリクエストの処理をブロックしているように見えます。
問題を説明するために、無限ループを持つサーバーを特徴とするサンプル コードを提供しました。 -loop goroutine (デフォルトでは無効) とクライアントが同時 HTTP リクエストを送信します。 goroutine を無効にすると、クライアントには予期された一連のアスタリスクが表示されます。ただし、これを有効にすると、いくつかのリクエストの後でクライアントの出力がブロックされます。
ゴルーチン内で runtime.LockOSThread を試した後でも、ブロックの解決に失敗するため、謎は残ります。 Go のドキュメントによると、runtime.LockOSthread は別のスレッドで無限ループを実行し、他のゴルーチンには影響を与えません。
この不可解な動作は、Go ランタイム スケジューラに起因する可能性があります。ある程度は先制的ですが、完全に先制的というわけではありません。 Go 1.2 では、関数呼び出し中に時折スケジューラーの呼び出しを強制することで改善が加えられました。ただし、この例の無限ループには関数呼び出しがないため、この解決策はバイパスされています。
無限ループ ハンドラーに意味のある作業を追加することを検討してください。あるいは、 runtime.Gosched を意図的に呼び出すと、ブロックの問題を軽減できる可能性があります。
以上が十分なリソースがあるにもかかわらず、無限ループのゴルーチンが Go HTTP サーバーをブロックするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。