func main () { wg := sync.WaitGroup {} wg.Add (10) for i := 0; i < 10; i++ { go func (JobSeq int) { defer wg.Done () // do something fmt.Printf ("the job: %d done.\n", JobSeq) }(i) } wg.Wait () }
输出结果
1 2 3 4 5 6 7 8 9 10
the job: 9 done. the job: 0 done. the job: 2 done. the job: 8 done. the job: 4 done. the job: 5 done. the job: 7 done. the job: 1 done. the job: 3 done. the job: 6 done.
func (wg *WaitGroup) Wait() { statep, semap := wg.state() for { state := atomic.LoadUint64(statep) v := int32(state >> 32) w := uint32(state) if v == 0 { return }
// 增加waiter计数器 if atomic.CompareAndSwapUint64(statep, state, state+1) { // 获取信号量 runtime_Semacquire(semap) if *statep != 0 { panic("sync: WaitGroup is reused before previous Wait has returned") } // 信号量获取成功 return } } }