- 条件变量:共享数据的状态发生变化时,通知阻塞在某个条件上的协程(线程)
- 条件变量是一个结构体,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
}