sync包提供了基本的同步基元,如互斥锁
但是这里不是讨论线程通信的问题(而线程通信应使用Channel)
以前使用time.Sleep(...)来保证线程执行完成, 显然线程执行所需要的时间不确定
sync里面有一个WaitGroup, 它是一个结构体, 可以用于等待线程执行
这样不用去估算线程需要执行多久
原理:
- 创建一个WaitGroup实例
- 添加要控制的线程数量
- 执行完一个线程时,总线程数量减1
- 等待所有线程执行完成, 若没有完成则处于阻塞状态
package main
import (
"fmt"
"sync"
)
func main() {
wg := sync.WaitGroup{} // 创建结构体实例, 用于控制协程任务
wg.Add(20) // 添加20个协程任务
for i:=0; i<10; i++ {
go func() { // 创建协程时, 未传递参数, i的会是是就近参数
fmt.Println("i = ", i)
wg.Done() // 完成一个协程, 总的协程任务减少1个
}()
}
for k:=0; k<10; k++ {
go func(k int) { // 创建协程时, 传递了参数, k的值是创建协程时传入的参数
fmt.Println("k = ", k)
wg.Done()
}(k)
}
wg.Wait() // 等待协程完成(处于阻塞状态, 直到全部协程任务完成)
}
注: 协程创建时, 不是马上执行, 一般是该协程处于就绪状态
同样, 在循环中创建的协程, 一般也不会马上执行
即循环不会等待协程执行, 而会继续下一次循环
什么时候执行协程, 这也是看系统调度(可能循环未完成时执行协程, 也可能循环都完成以后才执行一次协程)
注: 创建协程时, 如果传入了参数, 则执行协程时, 根据传入的参数来执行
创建协程时, 如果没有传入参数, 则执行协程时, 根据就近参数来执行