C++多线程编程第八讲--condition_variable、wait、notify_one、notify_all
/*condition_variable、wait、notify_one、notify_all*/
//(1)条件变量std::condition_variable()、wait()、notify_one()
// std::condition_variable()是一个类,需要和互斥量配合工作。
#include<iostream>
#include<thread>
#include<vector>
#include<list>
#include<mutex>
using namespace std;
class A
{
public:
//把收到的消息,入到一个队列中
void inMsgRecvQueue()
{
int i;
for (i = 0; i < 100000; ++i)
{
cout << "push_back num = " << i << endl;
//lock之后只能有一个线程可以对msgQueue队列做操作
unique_lock<mutex> my_unique_lock(my_mutex);
msgQueue.push_back(i); //数字i就是玩家的命令。
cond.notify_one(); //如果相应线程再阻塞,则将wait的线程唤醒。如果没有阻塞,则没有作用。
}
}
//把数据从消息队列中取出
void outMsgRecvQueue()
{
int command = 0;
while (true)
{
std::unique_lock<mutex> sbguard1(my_mutex);
//用来判断第二个参数的条件,如果返回值是false,那么wait将解锁互斥量,并阻塞到本行。
//直到其他线程调用notify_one或者notify_all唤醒此线程为止。如果wait不写第二个参数,默认第二个参数返回false。
//如果第二个参数返回true,则继续往下执行。
//阻塞后被别人唤醒后,wait就会不断的尝试重新获得互斥量锁。拿到锁后,再去判断第二个参数条件。
//如果阻塞后被唤醒没有第二个参数的情况下,这个时候第二个参数默认是true。
//这种方式可以减少资源消耗,不用一直判断队列是否为空。
cond.wait(sbguard1, [this] {
if (!msgQueue.empty())
{
return true;
}
else
{
return false;
}
});
command = msgQueue.front();
msgQueue.pop_front();
sbguard1.unlock();
cout << "command = " << command << endl;
}
}
private:
list<int> msgQueue;
mutex my_mutex; //创建一个互斥量
std::condition_variable cond;
};
int main()
{
A myobj;
thread myOutMsg(&A::outMsgRecvQueue, std::ref(myobj)); //保证线程中用的同一个对象
thread myInMsg(&A::inMsgRecvQueue, std::ref(myobj));
myOutMsg.join();
myInMsg.join();
cout << "main thread end..." << endl;
return 0;
}
//(2)上述代码深入思考
//(3)notify_all()
#include<iostream>
#include<thread>
#include<vector>
#include<list>
#include<mutex>
using namespace std;
class A
{
public:
//把收到的消息,入到一个队列中
void inMsgRecvQueue()
{
int i;
for (i = 0; i < 100000; ++i)
{
cout << "push_back num = " << i << endl;
//lock之后只能有一个线程可以对msgQueue队列做操作
unique_lock<mutex> my_unique_lock(my_mutex);
msgQueue.push_back(i); //数字i就是玩家的命令。
//如果多个相应线程在阻塞,则将wait的线程全部唤醒。如果没有阻塞,则没有作用。
cond.notify_all();
}
}
//把数据从消息队列中取出
void outMsgRecvQueue()
{
int command = 0;
while (true)
{
std::unique_lock<mutex> sbguard1(my_mutex);
cond.wait(sbguard1, [this] {
if (!msgQueue.empty())
{
return true;
}
else
{
return false;
}
});
command = msgQueue.front();
msgQueue.pop_front();
sbguard1.unlock();
cout << "command = " << command << endl;
}
}
private:
list<int> msgQueue;
mutex my_mutex; //创建一个互斥量
std::condition_variable cond;
};
int main()
{
A myobj;
thread myOutMsg1(&A::outMsgRecvQueue, std::ref(myobj)); //保证线程中用的同一个对象
thread myOutMsg2(&A::outMsgRecvQueue, std::ref(myobj));
thread myInMsg(&A::inMsgRecvQueue, std::ref(myobj));
myOutMsg1.join();
myOutMsg2.join();
myInMsg.join();
cout << "main thread end..." << endl;
return 0;
}
posted on 2021-10-19 08:41 xcxfury001 阅读(303) 评论(0) 收藏 举报
浙公网安备 33010602011771号