C++ 多线程笔记
条件变量 std::condition_variable 以及成员函数
条件变量condition_variable
std::condition_variable实际上是一个类,是一个和条件相关的类,说白了就是等待一个条件达成。
1 | std::condition_variable my_cond; |
wait()
wait()
第一个参数为std::unique_lock<std::mutex>
,第二个参数为可选参数【可调用对象如 lambda 表达式 或者 函数】
1 | class A { |
如果有第二个参数
如果第二个参数返回值为
false
那么wait()
将解锁互斥量,并堵塞到本行,堵塞到其他某个线程调用notify_one()
或者notify_all()
成员函数为止如果第二个参数返回值为
true
那么wait()
将重新解锁上互斥量,并继续执行之后的代码
如果没有第二个参数
- 就与第二个参数为
false
效果相同,将解锁互斥量,并堵塞到本行,堵塞到其他某个线程调用notify_one()
或者notify_all()
成员函数为止
- 就与第二个参数为
当唤醒其他线程中的 wait()
后
wait()
不断尝试重新获取互斥量的锁,如果获取不到 就会一直反复获取锁,如果获取到就继续执行 2.- 如果
wait()
有第二个参数(当前为 lambda 表达式)且返回值为false
那wait()
又对互斥量解锁并堵塞到这,等待再次被唤醒 - 如果
wait()
有第二个参数(当前为 lambda 表达式)且返回值为true
则wait()
返回,将互斥量再次上锁 流程继续(此时互斥量已经被锁住) - 如果 没有第二个参数
wait()
将互斥量再次上锁 直接返回,流程继续
- 如果
notify_one() 与 notify_all()
notify_one()
唤醒一个线程中的wait()
notify_all()
唤醒所有线程中的wait()
虚假唤醒
notify_one()
或者 notify_all()
唤醒 wait()
后,实际有些线程可能不满足唤醒的条件,就会造成虚假唤醒,可以在 wait()
中再次进行判断解决虚假唤醒。
解决:wait
中要有第二个参数(lambda),并且这个 lambda
中要正确判断所处理的公共数据是否存在。
深入思考
上面的代码可能导致出现一种情况:
因为outMsgRecvQueue()
与inMsgRecvQueue()
并不是一对一执行的,所以当程序循环执行很多次以后,可能在msgRecvQueue
中已经有了很多消息,但是,outMsgRecvQueue
还是被唤醒一次只处理一条数据。这时可以考虑把outMsgRecvQueue
多执行几次,或者对inMsgRecvQueue
进行限流。