package main import ( "fmt" "sync" "time" ) var wg = sync.WaitGroup{} func do(i int) { // 将WaitGroup计数器减1,也可改为“wg.Add(-1)”,看源码可知wg.Done()就是wg.Add(-1) defer wg.Done() time.Sleep(time.Second * time.Duration(i)) // 休眠i秒钟 fmt.Printf("i = %v \n", i) } func main() { for i := 0; i < 10; i++ { wg.Add(1) // 启动协程前将WaitGroup计数器加1 go do(i) // 启动协程执行任务 } wg.Wait() // 这里会一直阻塞,直到WaitGroup计数器为0 } //========== 输出过程·开始 ==========// // i = 0 // i = 1 // i = 2 // i = 3 // i = 4 // i = 5 // i = 6 // i = 7 // i = 8 // i = 9 //========== 输出过程·结束 ==========// //========== 总结 ==========// // 1、sync.WaitGroup的主要作用是保证所有协程任务都能得到执行,例如我们启动1000个协程分别爬1000个网页,很明显开发者是无法预 // 估爬完1000个页面所需要的时间的,所以不可能在主线程中使用time.Sleep()将程序阻塞,而sync.WaitGroup则能够将程序阻塞到所 // 有协程任务完成为止,不需要管这些任务要执行多长时间。 // 2、WaitGroup的使用很简单,总共只有Add()、Done()、Wait()三个方法,需要注意的是Add()和Done()必须成对出现,即WaitGroup计数 // 器执行了加1操作必须要在某处将WaitGroup计数器减1,否则会出现deadlock,并且如果WaitGroup计数器为负数则会报panic。
Copyright © 2025 码农人生. All Rights Reserved