GO sync.WaitGroup
需求
执行完所有子函数后退出主程序
#1. 串行执行
import ( "fmt" "time" ) func f1Sleep(val int) { time.Sleep(time.Duration(val)) fmt.Println(val) } func try0() { fmt.Println("Start") start := time.Now() arr := []int{1, 7, 3, 2, 5} for _, v := range arr { f1Sleep(v * 1000000000) } end := time.Now() fmt.Println("Done", end.Sub(start)) } func main() { try0() }
执行:
Start 1000000000 7000000000 3000000000 2000000000 5000000000 Done 18.019475023s
问题:性能慢
#2. 并发执行
import ( "fmt" "time" ) func f1Sleep(val int) { time.Sleep(time.Duration(val)) fmt.Println(val) } func try0() { fmt.Println("Start") start := time.Now() arr := []int{1, 7, 3, 2, 5} for _, v := range arr { go f1Sleep(v * 1000000000) } time.Sleep(10 * 1000000000) end := time.Now() fmt.Println("Done", end.Sub(start)) } func main() { try0() }
执行:
Start 1000000000 2000000000 3000000000 5000000000 7000000000 Done 10.004520653s
问题:主程序到底sleep多杀,还得自己控制,无法智能控制
sync.WaitGroup 解决协程同步和通讯
#3. 并发执行
import ( "fmt" "sync" "time" ) var wg sync.WaitGroup func f1Sleep(val int) { defer wg.Done() time.Sleep(time.Duration(val)) fmt.Println(val) } func try1() { fmt.Println("Start") start := time.Now() arr := []int{1, 7, 3, 2, 5} for _, v := range arr { wg.Add(1) go f1Sleep(v * 1000000000) } wg.Wait() end := time.Now() fmt.Println("Done", end.Sub(start)) } func main() { try1() }
执行:
Start 1000000000 2000000000 3000000000 5000000000 7000000000 Done 7.003296504s
sync.WaitGroup只有3个方法:
- Add():添加计数中
- Done():是Add(-1)的别名,用途是减掉一个计数
- Wait():计数不为0时阻塞的运行
其他知识点
#1 计算时间差
start := time.Now()
// pass
end := time.Now()
end.Sub(start)
#2 sleep参数单位是:Duration, 是纳秒
1秒=1000毫秒(ms)
1秒=1,000,000 微秒(μs)
1秒=1,000,000,000 纳秒(ns)