ホームページ  >  記事  >  バックエンド開発  >  Go で Goroutine を正しく同期するには、「wg.Add()」と「wg.Done()」をどこに配置する必要がありますか?

Go で Goroutine を正しく同期するには、「wg.Add()」と「wg.Done()」をどこに配置する必要がありますか?

Susan Sarandon
Susan Sarandonオリジナル
2024-11-04 05:28:29793ブラウズ

 Where Should You Place `wg.Add()` and `wg.Done()` for Correct Goroutine Synchronization in Go?

Goroutine 同期のための WaitGroup 挿入配置

Go では、sync.WaitGroup 型は、アクティブなゴルーチンの数を追跡することによってゴルーチン間の同期を容易にします。 goroutine を実行し、すべての goroutine の実行が完了するまで待ってから次に進みます。 wg.Add() 呼び出しと wg.Done() 呼び出しを適切に配置することは、正しい動作を保証するために重要です。

次のコードを考えてみましょう。

<code class="go">var wg sync.WaitGroup
var v int32 = 0 
for i = 0; i < 100; i++{
   go func(){
       wg.Add(1) // wrong place
       atomic.AddInt32(&v,1)
       wg.Done()
   } 
}
wg.Wait()
fmt.Println(v)</code>

この例では、wg.Add( 1) が誤って匿名関数内に配置されています。この不適切な配置により、v の値が矛盾し、多くの場合 100 未満になる可能性があります。

この不一致の理由は、ゴルーチンの同時実行性の性質にあります。ゴルーチン内に配置すると、wg.Add(1) が wg.Done() と同時に実行される可能性があり、wg.Wait() が途中で再開され、完了したゴルーチンの数が過小評価されることがあります。

この問題に対処するには、 wg.Add(1) は、各ゴルーチンを起動する前に for ループに配置する必要があります:

<code class="go">var wg sync.WaitGroup
var v int32 = 0 
for i = 0; i < 100; i++{
   wg.Add(1)
   go func(){
       atomic.AddInt32(&v,1)
       wg.Done()
   } 
}
wg.Wait()
fmt.Println(v)</code>

この調整により、すべての wg.Done() 呼び出しが完了するまで wg.Wait() がブロックされるようになります。 v が完了したゴルーチンの数を正確に反映できるようにします。

要約すると、適切な同期と信頼性の高い結果を確保するために、ゴルーチンを起動する前に常に wg.Add() を配置し、ゴルーチンの実行が完了したら wg.Done() を配置します。計算。

以上がGo で Goroutine を正しく同期するには、「wg.Add()」と「wg.Done()」をどこに配置する必要がありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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