The Add method changes a sync.WaitGroup counter: positive values register operations, while negative values—typically through Done—finish them. Wait blocks until the counter reaches zero; a negative counter panics. section 9.11
A frequent mistake is calling wg.Add(1) inside the goroutine it is meant to register. The parent may reach wg.Wait before that call, observe a zero counter, and continue while work is still running. section 9.11
Incorrect registration
for i := 0; i < 3; i++ { go func() { wg.Add(1) atomic.AddUint64(&v, 1) wg.Done() }() } wg.Wait() fmt.Println(v) This can print any value from 0 to 3: the parent can return from Wait before the last goroutine increments the counter and updates v. section 9.11
Register work before starting it:
- Use atomic operations for shared counters, but do not treat atomic updates as a substitute for WaitGroup synchronization. section 9.11
