1--std::condition_variable
std::condition_variable creates a condition variable object, which can use wait(), notify_one() and other member functions to achieve multi-threaded conditional interaction. The specific usage is as follows:
#include <iostream>
#include <thread>
#include <mutex>
#include <list>
#include <condition_variable>
class Sample{
public:
// 模型发送消息
void inMsgRecvQueue(){
for(int i = 0; i < 1000; i++){
std::cout << "Running inMsgRecvQueue(), insert one elem" << i << std::endl;
std::unique_lock<std::mutex> guard1(mutex1);
msgRecvQueue.push_back(i);
// 将wait()所在线程唤醒
// 假如wait()所在线程正在执行其余代码段,并不处于wait()的状态,此时notify_one()无效果
cond.notify_one();
}
return;
}
// 模拟取消息
void outMsgRecvQueue(){
int command = 0;
while(true){
std::unique_lock<std::mutex> guard1(mutex1);
// wait()用于等待,当lambda表达式返回true时,wait()直接返回
// 当lambda表达式返回false时,wait()将解锁互斥量,并在本行堵塞
// 堵塞直到某个线程调用notify_one()成员函数为止
// 如果wait()没有第二个参数,则与lambda表达式返回false的效果一样
// 即在本行堵塞,直到某个线程调用notify_one()成员函数
// 当其他线程用notify_one()堵塞的wait()唤醒后,wait()线程将不断尝试获取锁
// 当wait()成功获取锁后,将加锁并执行里面的内容(重新判断lambda表达式)
cond.wait(guard1, [this]{
if(!msgRecvQueue.empty()) return true;
else return false;
});
// lambda表达式返回true,执行下面的内容
command = msgRecvQueue.front();
msgRecvQueue.pop_front();
guard1.unlock(); // unique_lock可以随时解锁
std::cout << "Running outMsgRecvQueue(), get one elem: "<< command << std::endl;
if(command == 999) break;
}
}
private:
std::mutex mutex1;
std::list<int> msgRecvQueue;
std::condition_variable cond;
};
int main(int argc, char *argv[]){
Sample sample1;
std::thread OutMsg(&Sample::outMsgRecvQueue, &sample1);
std::thread InMsg(&Sample::inMsgRecvQueue, &sample1);
OutMsg.join();
InMsg.join();
return 0;
}
2--notify_one()和notify_all()
notify_one() can only wake up one thread, when multiple threads are waiting to be woken up, only one will be woken up randomly;
notify_all() can wake up multiple threads at the same time. When multiple threads are waiting to be woken up, all threads will be woken up; (multiple threads that are woken up may compete for the same mutex (assuming the threads share a lock))