条件变量:共享数据的状态发生变化时,通知阻塞在某个条件上的协程(线程) 条件变量是一个结构体,Cond.L要搭配锁一起使用
type Cond struct {
noCopy noCopy
L Locker
notify notifyList
checker copyChecker
}
三个常用方法:
func (c *Cond) Wait()
a) 阻塞等待条件变量满足 b) 释放已掌握的互斥锁相当于cond.L.Unlock()。 注意:两步为一个原子操作。 c) 当被唤醒,Wait()函数返回时,解除阻塞并重新获取互斥锁。相当于cond.L.Lock()func (c *Cond) Signal()
package main
import "fmt"
import "sync"
import "math/rand"
import "time"
var cond sync. Cond
func producer ( out chan <- int , idx int ) {
for {
cond. L. Lock ( )
for len ( out) == 3 {
cond. Wait ( )
}
num := rand. Intn ( 1000 )
out <- num
fmt. Printf ( "%dth 生产者,产生数据 %3d, 公共区剩余%d\n" , idx, num, len ( out) )
cond. L. Unlock ( )
cond. Signal ( )
time. Sleep ( time. Second)
}
}
func consumer ( in <- chan int , idx int ) {
for {
cond. L. Lock ( )
for len ( in) == 0 {
cond. Wait ( )
}
num := <- in
fmt. Printf ( "---- %dth 消费者, 消费数据 %3d,公共区剩余%d\n" , idx, num, len ( in) )
cond. L. Unlock ( )
cond. Signal ( )
time. Sleep ( time. Millisecond * 500 )
}
}
func main ( ) {
rand. Seed ( time. Now ( ) . UnixNano ( ) )
quit := make ( chan bool )
product := make ( chan int , 3 )
cond. L = new ( sync. Mutex)
for i := 0 ; i < 5 ; i++ {
go producer ( product, i+ 1 )
}
for i := 0 ; i < 5 ; i++ {
go consumer ( product, i+ 1 )
}
<- quit
}