1--std::condicion_variável
std::condition_variable cria um objeto de variável de condição, que pode usar wait(), notify_one() e outras funções de membro para obter interação condicional multiencadeada. O uso específico é o seguinte:
#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() e notify_all()
notify_one() só pode ativar um thread e, quando vários threads estiverem esperando para serem ativados, apenas um será ativado aleatoriamente;
notify_all() pode ativar várias threads ao mesmo tempo. Quando várias threads estiverem esperando para serem ativadas, todas as threads serão ativadas; (várias threads que são ativadas podem competir pelo mesmo mutex (assumindo que as threads compartilham um bloqueio ))