Home > Article > Backend Development > Why is the Placement of `wg.Add()` Crucial for Proper Synchronization in Go\'s `sync.WaitGroup`?
Correcting wg.Add() Placement for WaitGroup Synchronization
In Go, the sync.WaitGroup type provides synchronization between goroutines. Its primary purpose is to enable the main goroutine to wait for a group of goroutines to complete their tasks. However, the placement of wg.Add() calls is crucial for ensuring proper synchronization.
In the incorrect example:
<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>
The wg.Add(1) call is placed inside the anonymous function, which is a mistake. This misguided placement can lead to a situation where wg.Wait() returns prematurely because wg.Add(1) is executed after wg.Done() within the same goroutine. As a result, v will not accurately reflect the number of completed tasks, and its value will likely be less than 100.
In the corrected example:
<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>
The wg.Add(1) call is now placed outside the anonymous function, ensuring that the main goroutine has invoked all 100 goroutines and registered their completion tasks with wg before calling wg.Wait(). This correct placement guarantees that wg.Wait() will block until all 100 goroutines have completed their tasks, resulting in an accurate value of v.
General Rules for Using sync.WaitGroup:
To ensure successful synchronization using sync.WaitGroup, follow these guidelines:
The above is the detailed content of Why is the Placement of `wg.Add()` Crucial for Proper Synchronization in Go\'s `sync.WaitGroup`?. For more information, please follow other related articles on the PHP Chinese website!