condition_variable的使用以及与锁的关系

条件变量和互斥锁是多线程的同步和互斥最基础的两种工具,其中互斥锁使用和功能都比较简单,条件变量在使用和理解起来相对就比较困难,不少初学者对于wait函数必须结合一个锁来使用的原则感到困惑,其实官方指导中已经有详尽的解释和案例,但讲的比较简洁,这里从wait函数执行流程来看下条件变量的使用方法和原理。

正确使用流程
thread1:

locker.lock()							---1
cv.wait(locker,pred)

wait函数展开如下:

while(!pred())							---2         
	等待signal,并调用locker.unlock()		---3
	接受signal返回并调用locker.lock()		---4

thread2:

locker.lock()							---5
change pred								---6
cv.signal()								---7
locker.unlock()							---8

从以上流程来看,无论thread1还是thread2先启动,都能实现想要的效果,先看看假设thread1先启动,执行流程:1,2,3,此时thread1进入block状态等待signal,thread2无论在1,2,3的哪一步启动,启动后执行流程都是5,6,7,8,然后thread1执行4,然后进行下一轮循环,判定条件成功,跳出循环,进入下一步。
再看看假设thread2先启动,执行流程为:5,6,7,8,此时无乱thread1在哪一步启动,执行顺序都为1,2,thread1在进行第一轮条件判断时直接跳过等待进入下一步。

去掉锁的使用流程
那么假设没有加锁会发生什么:
thread1:

cv.wait(locker,pred)

wait函数展开如下:

while(!pred())					---1         
	wait(),blocked				---2
	wait()返回					---3

thread2:

change pred						---4
cv.signal()						---5

直观上来看,很显然,首先pred并不能保证线程安全,当两个线程同时访问这个资源时可能发生不可预料的结果,即使没有发生,来看看假设两个线程以这样的步骤来执行:1,4,5,2,即使thread2已经改变了pred且发出了signal,但由于thread1此时还未处于等待状态,此signal将被忽略。

总结
从上面的整个流程对比来看,可以看出加锁主要有两方面的作用:

  1. 保护pred资源,避免多线程同时读写该资源
  2. 保证等待线程中pred的读操作和wait操作的原子性
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值