- **1.
- Gọi
Addbên trong goroutine. Tài liệu yêu cầuAddphải xảy ra trước**Wait. - Đặt
Add(1)trong goroutine thìWaitcó thể chạy khi bộ đếm vẫn là 0 và trả về ngay, bỏ qua toàn bộ công việc.
go
for _, j := range jobs {
go func(j Job) {
wg.Add(1) // wrong: Wait may already have returned
defer wg.Done()
run(j)
}(j)
}
wg.Wait()2. Truyền WaitGroup theo giá trị. func worker(wg sync.WaitGroup) nhận một bản sao; Done giảm bộ đếm của bản sao, bản gốc không bao giờ về 0 → Wait treo mãi. Phải truyền *sync.WaitGroup. go vet bắt lỗi này qua analyzer copylock.
3. Thiếu Done trên nhánh lỗi. Có return sớm mà không giảm bộ đếm → treo. Luôn đặt defer wg.Done() ở dòng đầu của goroutine.
4. Done nhiều hơn Add → panic: sync: negative WaitGroup counter.
5. Tái dùng khi Wait chưa xong → panic: WaitGroup is reused before previous Wait has returned.
Go 1.25 thêm wg.Go(fn) gộp Add(1) + go + defer Done() vào một lời gọi, loại bỏ luôn nhóm lỗi 1, 3 và 4:
go
for _, j := range jobs {
wg.Go(func() { run(j) })
}
wg.Wait()