sync.Cond是用来控制某个条件下,goroutine进入等待时期,等待信号到来,然后重新启动
package main
import (
"fmt"
"sync"
"time"
)
func main() {
locker := new(sync.Mutex)
cond := sync.NewCond(locker)
done := false
cond.L.Lock()
go func() {
time.Sleep(2e9)
done = true
cond.Signal()
}()
if !done {
cond.Wait()
}
fmt.Println("now done is ", done)
}
这里当主goroutine进入cond.Wait的时候,就会进入等待,当从goroutine发出信号之后,主goroutine才会继续往下面走。
sync.Cond还有一个BroadCast方法,用来通知唤醒所有等待的gouroutine。
package main
import (
"fmt"
"sync"
"time"
)
var locker = new(sync.Mutex)
var cond = sync.NewCond(locker)
func test(x int) {
cond.L.Lock() //获取锁
cond.Wait() //等待通知,暂时阻塞
fmt.Println(x)
time.Sleep(time.Second) //每秒输出一个
cond.L.Unlock() //释放锁,不释放的话将只会有一次输出
}
func main() {
for i := 0; i < 40; i++ {
go test(i)
}
fmt.Println("start all")
cond.Broadcast() //下方广播给所有等待的goroutine
time.Sleep(time.Second * 60)
}
主gouroutine开启后,可以创建多个从gouroutine,从gouroutine获取锁后,进入cond.Wait状态,当主gouroutine执行完任务后,通过BroadCast广播信号。 处于cond.Wait状态的所有gouroutine收到信号后将全部被唤醒并往下执行。需要注意的是,从gouroutine执行完任务后,需要通过cond.L.Unlock释放锁, 否则其它被唤醒的gouroutine将没法继续执行。
参考文章:
登陆发表评论