boost thread usage

1 Condition
notify和notifyAll()并不释放锁,只是唤醒阻塞在wait方法的线程去参与获得锁的竞争了,但不是马上得到锁,因为锁还在notify和notifyAll()所在线程手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后到scoped_lock锁的作用域结束才会释放scoped_lock锁。

如果std::condition_variable对象调用了wait方法,该函数会自动调用 lck.unlock()释放锁(注意:此时只是通过unlcok释放掉了mutex,而lck对象还是存在的),然后处于block等待状态。另外,一旦当前线程获得通知(notified,通常是另外某个线程调用 notify_* 唤醒了当前线程),wait() 函数也是自动调用 lck.lock(),使得 lck 的状态和wait函数之前被调用时相同。


notify()和notifyAll()都是std::condition_variable对象用于通知处在等待该对象的线程的方法。两者的最大区别在于:
notifyAll使所有阻塞在该std::condition_variable对象上的wait函数的线程统统unblock wait函数并且wait函数继续执行后会去竞争该std::condition_variable对象上的锁。如果其中的某一个竞争中获胜,得到了该std::condition_variable对象上的锁,它就会马上lock住该锁,并且退出wait函数;其它竞争中失败的wait状态等待的线程,则会阻塞在lck.lock()获取锁上,直到之前获取到锁的线程释放掉锁之后才可能获取到锁继续执行。

notify则只是随机选择一个wait状态线程进行通知(如果有多个线程处于wait状态),并使它获得该std::condition_variable对象上的锁,但不通知其他同样在等待被该std::condition_variable对象notify的线程们。当该被通知的线程释放掉了对象上的锁后,如果该对象接下来没有调用用notify或notifyAll语句,则其他wait状态等待的线程由于没有得到该对象的通知,依然继续处在wait状态,直到这个对象发出一个notify或notifyAll。它们等待的是被notify或notifyAll,而不是锁。


condition是一个简单的同步对象,两个线程有共用的变量交互的情况下,用于使一个线程等待一个特定的条件成立(此条件在别的线程中是可以改变的)。一个condition对象总是和一个mutex对象配合使用。mutex在交给condition对象的wait系列函数时,必须已经通过lock对象加上了锁。当线程陷入等待时(即进入wait()函数),condtion对象将释放mutex上的锁,当wait获得notify通知唤醒时,wait会调用lck.lock()去竞争获取锁。


当 std::condition_variable 对象的某个wait 函数被调用的时候,当前线程会一直被阻塞,直到另外一个线程在相同的 std::condition_variable 对象上调用了 notification 函数来唤醒当前线程。


用condition的好处就:
一个线程在获得mutex锁后,去执行critical section code,但是因为里面的if条件不成立的话则里面的代码就不能被执行到,而且辛辛苦苦获得的mutex锁也要释放掉。只能再等下一次机会获取mutex锁,再去判断条件是否成立。这样的话获得mutex的时间和if之前的代码都是白执行了,效率低下。但是如果用condition的话呢,则在条件不成立的位置可以在当前语句wait,等待外部线程去改变该条件,当外部线程改变了该条件后就通知该线程继续判断条件是否成立,如果成立则接着往下执行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值