条件变量
Posted huyuan1004
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了条件变量相关的知识,希望对你有一定的参考价值。
本身不是锁,但是经常和锁结合使用
使用流程:
创建 条件变量:var cond sync.Cond
指定条件变量用的 锁: cond.L = new(sync.Mutex)
cond.L.Lock() 给公共区加锁(互斥量)
判断是否到达 阻塞条件(缓冲区满/空) —— for 循环判断
for len(ch) == cap(ch) cond.Wait() —— 1) 阻塞 2) 解锁 3) 加锁
访问公共区 —— 读、写数据、打印
解锁条件变量用的 锁 cond.L.Unlock()
唤醒阻塞在条件变量上的 对端。 signal() Broadcast()
package main
import (
"fmt"
"math/rand"
"time"
"sync"
)
var cond sync.Cond
func producer(out chan <- int,idx int)
for
cond.L.Lock() // 条件变量对应互斥锁加锁
for len(out) == 3 // 产品区满,等待消费者消费
cond.Wait() // 挂起当前go程,等待条件变量满足,被消费者唤醒
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 < 3;i++
go consumer(product,i+1)
<-quit
以上是关于条件变量的主要内容,如果未能解决你的问题,请参考以下文章
[C++11 多线程同步] --- 条件变量的那些坑条件变量信号丢失和条件变量虚假唤醒(spurious wakeup)
[C++11 多线程同步] --- 条件变量的那些坑条件变量信号丢失和条件变量虚假唤醒(spurious wakeup)