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将没法继续执行。


参考文章:



登陆发表评论