ホームページ >バックエンド開発 >Golang >無限ループするゴルーチンを終了する安全な方法は?

無限ループするゴルーチンを終了する安全な方法は?

WBOY
WBOY転載
2024-02-06 09:09:04988ブラウズ

终止无限循环 goroutine 的安全方法?

質問の内容

リスナーとして機能する goroutine があります。入力ストリームはバッファリングされた channel に入力されるので、そのチャンネルに入力されるデータを goroutine で処理したいと考えています。ただし、channel は一時的にデータ入力がない場合があります。 channel が一瞬何も提供できない場合は、ゴルーチンに別のことを実行してもらいたいと考えています。関数は次のようになります:

リーリー

問題は、そのチャネルを通過するすべてのものを印刷したいということです。 main が突然終了すると、arr にまだ出力されていないものが残っている可能性があり、それを見ることができなくなります。したがって、プログラムが終了する前に、このゴルーチンがチャネル内のすべてのデータを処理することを確認する必要があります。これは、ゴルーチンが必要な作業を完了する前にプログラムがシャットダウンしないようにするために、WaitGroupWait() を使用する必要があることを意味すると思います。 しかし、Done()WaitGroup のどこで呼び出されるのかわかりません。

基本的には、プログラムが終了する前に goroutine を「一時停止」し、残っているものを出力する安全な方法が必要です。これどうやってするの?

さらに悪いことに、単体テストなどの場合、自分でチャネルにデータを送信し、ある程度の量を送信した後、配列を表示したいと考えています。ただし、データをチャネルに送信するコードの直後に配列をチェックするだけの場合、ゴルーチンはまだすべてのデータを処理する機会を持っていない可能性があります。この場合、Goroutine が送信したすべてのデータを処理するのを待ってから、Goroutine を一時停止して、配列を表示するように依頼したいと考えています。しかし、Goroutine の処理がいつ終了したかをどうやって知ることができるのでしょうか?しばらく 寝て 、完了するチャンスを与えてから、立ち止まって見ることもできますが、それはかなり危険なように感じます。この問題を解決するベストプラクティスがあると思いますが、まだわかりません。

ここに私が考えたアイデアがいくつかありますが、うまくいったものはありませんでした。

  1. 無限 for ループの外で Done() を呼び出します。私の知る限り、コードにアクセスできないため、これは機能しません。

  2. タイムアウト caseDone() を呼び出します。これは機能しません。タイムアウト後にさらにデータが送信される可能性があり、Goroutine がリッスンし続けたいからです。


正解


チャネルが閉じられたときに返されるようにリスナーを変更します。戻り時に wg.Done() を呼び出します:

リーリー

送信完了後にチャネルを閉じるように main を変更します。メインから戻る前に、ゴルーチンが完了するのを待ちます。

リーリー

以上が無限ループするゴルーチンを終了する安全な方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はstackoverflow.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。