以下の Go コードでは、変数 v が予想よりも小さいことがよくあります。 wg.Add().
<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() は、対応するゴルーチンを起動する前に常に呼び出す必要があります。これにより、メインのゴルーチンがすべてのゴルーチンをブロックするようになります。ゴルーチンが wg.Done() を実行しました。
<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.Add() がゴルーチン内に配置されている場合、すべてのゴルーチンが完了するまでメインのゴルーチンがブロックされることは保証できません。 。これは、ゴルーチンが同時に実行され、実行順序が決定的でないためです。
ゴルーチンの前に wg.Add() を配置することで、メインのゴルーチンが到達する前に wg.Add() を 100 回呼び出すことが保証されます。 wg.Wait()。これにより、100 個のゴルーチンすべてが wg.Done() を呼び出すまでメインのゴルーチンがブロックされ、v が常に 100 に等しくなります。
sync.WaitGroup を使用する場合は、次に従ってください。ガイドライン:
以上がGo で同期を保証するには、なぜ wg.Add() の配置が重要なのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。