条件变量

c++11

std::condition_variable

说明

条件变量(condition variable)是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待某个条件为真,而将自己挂起;另一个线程使的条件成立,并通知等待的线程继续。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。

Any thread that intends to wait on std::condition_variable has to
1、acquire a std::unique_lock, on the same mutex as used to protect the shared variable
获得锁
2、execute wait, wait_for, or wait_until. The wait operations atomically release the mutex and suspend the execution of the thread.
执行wait操作,会自动释放锁并挂起线程
3、When the condition variable is notified, a timeout expires, or a spurious wakeup occurs, the thread is awakened, and the mutex is atomically reacquired. The thread should then check the condition and resume waiting if the wake up was spurious.
当条件满足,线程唤醒,自动获取锁。需要提防虚假唤醒。

wait

std::condition_variable::wait

Atomically releases lock, blocks the current executing thread, and adds it to the list of threads waiting on *this. The thread will be unblocked when notify_all() or notify_one() is executed. It may also be unblocked spuriously. When unblocked, regardless of the reason, lock is reacquired and wait exits. If this function exits via exception, lock is also reacquired. (until C++14)
wait的行为:自动释放锁,阻塞(挂起?)当前线程;通过notify_all() 唤醒线程,同时重新获得锁。

虚假唤醒
说明
在多核处理器下,notify_all()可能会激活多于一个线程(阻塞在条件变量上的线程)。结果是,当一个线程调用notify_all()后,多个调用wait()或wait_for()的线程返回。这种效应称为为”虚假唤醒”(spurious wakeup)。
虽然虚假唤醒在wait()函数中可以解决,为了发生概率很低的情况而降低边缘条件(fringe condition)效率是不值得的,纠正这个问题会降低对所有基于它的所有更高级的同步操作的并发度。所以wait()的实现上没有去解决它。
所以通常的标准解决办法是这样的:将条件的判断从if 改为while

while(条件不满足){  
   wait();  
}  
而不是:  
If( 条件不满足 ){  
   wait();  
}  

wait中的while()不仅仅在等待条件变量前检查条件,实际上在等待条件变量后也检查条件。
这样对条件进行多做一次判断,即可避免“虚假唤醒”.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值