ホームページ  >  記事  >  バックエンド開発  >  My Go sync.WaitGroup が完了しないのはなぜですか?

My Go sync.WaitGroup が完了しないのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-11-27 04:57:14285ブラウズ

Why Doesn't My Go sync.WaitGroup Ever Complete?

Golang sync.WaitGroup Never Completes

提供されたコードは、URL のリストを取得し、条件付きでファイルをダウンロードしてファイルに保存することで同時実行性を示します。システム。メインのゴルーチンは、sync.WaitGroup を使用してすべてのファイルがフェッチされるのを待ちます。ただし、すべてのリクエストが完了した後でもプログラムは終了できません。

この問題を理解するには、WaitGroup の機能を考慮してください。実行中のゴルーチンの数を維持します。カウントがゼロに達すると、waitgroup はすぐに戻り、すべてのゴルーチンの実行が完了したことを示します。

指定されたコードでは、WaitGroup の Add メソッドを使用してカウントをインクリメントし、Done メソッドを使用してカウントをデクリメントします。 。 Add メソッドが Done メソッドよりも多く呼び出された場合、またはその逆の場合、WaitGroup はゼロに達せず、メインのゴルーチンが無期限に待機することになります。

提供されたコードには 2 つのエラーがあります。

  1. downloadFromURL 関数は、WaitGroup へのポインターではなく、WaitGroup のコピーを受け取ります。これにより、WaitGroup の内部データのコピーが渡されるため、関数内で行われた変更 (Done の呼び出しなど) はメインの goroutine には表示されません。この問題を解決するには、代わりに WaitGroup へのポインターを渡します。
func main() {
    ...
    go downloadFromURL(url, &wg)
    ...
}
  1. defer wg.Done() ステートメントは、downloadFromURL 関数の最初のステートメントとして配置されません。 Done を呼び出す前にエラーが発生したり、他のロジックが実行された場合、デクリメント操作は登録されず、WaitGroup のカウントは 0 に達しません。これを修正するには、 defer wg.Done() が関数の最初のステートメントであることを確認します。
func downloadFromURL(url string, wg *sync.WaitGroup) error {
    defer wg.Done()
    ...
}

これらの修正を適用すると、WaitGroup は正しく機能し、ゴルーチンが完了するにつれてカウントが減ります。タスクを実行し、最終的にメインのゴルーチンの正常な終了につながります。

以上がMy Go sync.WaitGroup が完了しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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