1--std::condition_variable
std::condition_variable は、wait()、notify_one()、およびその他のメンバー関数を使用してマルチスレッドの条件付き対話を実現できる条件変数オブジェクトを作成します。具体的な使用方法は次のとおりです。
#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()
Notice_one() は 1 つのスレッドのみをウェイクアップできます。複数のスレッドがウェイクアップを待機している場合、ランダムに 1 つだけがウェイクアップされます。
Notice_all() は複数のスレッドを同時にウェイクアップできます。複数のスレッドがウェイクアップを待っている場合、すべてのスレッドがウェイクアップされます (ウェイクアップされた複数のスレッドが同じミューテックスを競合する可能性があります (スレッドがロックを共有していると仮定すると) ))