condition_variable中的和wait_once和notify_one及notify_all实例代码
// ConsoleApplication6.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include<thread> #include<iostream> #include<list> #include<mutex> using namespace std; mutex mut_one; once_flag gl_flag;//标记 class A { private: list<int> msgRecvQueue; mutex my_mutex;
my_cond;//生成一个条件对象 static A* Instance; public: static A* GetInstance() { if (Instance == NULL) { unique_lock<mutex> my(mut_one); if (Instance == NULL) { Instance = new A; static A_Guard gl; } } return Instance; } class A_Guard { public: ~A_Guard() { if (A::Instance != NULL) { delete A::Instance; A::Instance = NULL; } } }; void enmsg() { for (int i = 1; i <= 100; i++) { msgRecvQueue.push_back(i); cout << "压入数据成功,数据为:" << i << endl; my_cond.notify_one();//作用是为了唤醒堵塞的wait } } void outmsg() { int command = 0; while (true) { unique_lock<mutex> sbg(my_mutex); my_cond.wait(sbg, [this] { if (!msgRecvQueue.empty()) return true; else return false; });//第二个参数如果返回false,wait会解锁,并堵塞在这一行等待notify_one //上面假设notify_one执行了唤醒的操作,那么第二个参数里面的list就不为空了,会返回true, //返回true之后也就意味着不堵塞了,继续执行以下的代码 command = msgRecvQueue.front(); cout << "弹出来的数据是" << command << endl; msgRecvQueue.pop_front(); } } }; A* A::Instance = NULL; void Thread_one() { A *s = A::GetInstance(); s->enmsg(); } void Thread_two() { A*s = A::GetInstance(); s->outmsg(); } int main() { thread thone(Thread_one); thread thtwo(Thread_two); thone.join(); thtwo.join(); return 0; }
把notify_one变为notify_all的代码:
// ConsoleApplication6.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include<thread> #include<iostream> #include<list> #include<mutex> using namespace std; mutex mut_one; once_flag gl_flag;//标记 class A { private: list<int> msgRecvQueue; mutex my_mutex; condition_variable my_cond;//生成一个条件对象 static A* Instance; public: static A* GetInstance() { if (Instance == NULL) { unique_lock<mutex> my(mut_one); if (Instance == NULL) { Instance = new A; static A_Guard gl; } } return Instance; } class A_Guard { public: ~A_Guard() { if (A::Instance != NULL) { delete A::Instance; A::Instance = NULL; } } }; void enmsg() { for (int i = 1; i <= 100; i++) { msgRecvQueue.push_back(i); cout << "压入数据成功,数据为:" << i << endl; //my_cond.notify_one();//作用是为了唤醒堵塞的wait my_cond.notify_all();//故名思意,唤醒的不知一个wait } } void outmsg() { int command = 0; while (true) { unique_lock<mutex> sbg(my_mutex); my_cond.wait(sbg, [this] { if (!msgRecvQueue.empty()) return true; else return false; });//第二个参数如果返回false,wait会解锁,并堵塞在这一行等待notify_one //上面假设notify_one执行了唤醒的操作,那么第二个参数里面的list就不为空了,会返回true, //返回true之后也就意味着不堵塞了,继续执行以下的代码 command = msgRecvQueue.front(); cout << "弹出来的数据是" << command << endl; msgRecvQueue.pop_front(); } } }; A* A::Instance = NULL; void Thread_one() { A *s = A::GetInstance(); s->enmsg(); } void Thread_two() { A*s = A::GetInstance(); s->outmsg(); } void Thread_three() { A*s = A::GetInstance(); s->outmsg(); } int main() { thread thone(Thread_one); thread thtwo(Thread_two); thread three(Thread_three); thone.join(); thtwo.join(); three.join(); return 0; }
把其中的一部分拿出来分析一下,比如这段代码:
while (true) { unique_lock<mutex> sbg(my_mutex); my_cond.wait(sbg, [this] { if (!msgRecvQueue.empty()) return true; else return false; });//第二个参数如果返回false,wait会解锁,并堵塞在这一行等待notify_one //上面假设notify_one执行了唤醒的操作,那么第二个参数里面的list就不为空了,会返回true, //返回true之后也就意味着不堵塞了,继续执行以下的代码 command = msgRecvQueue.front(); cout << "弹出来的数据是" << command << endl; msgRecvQueue.pop_front(); }
变为:
while (true) { unique_lock<mutex> sbg(my_mutex); my_cond.wait(sbg, [this] { if (!msgRecvQueue.empty()) return true; else return false; });//第二个参数如果返回false,wait会解锁,并堵塞在这一行等待notify_one //上面假设notify_one执行了唤醒的操作,那么第二个参数里面的list就不为空了,会返回true, //返回true之后也就意味着不堵塞了,继续执行以下的代码 sbg.unlock();//把锁打开了 chrono::milliseconds dura(2000); this_thread::sleep_for(dura); command = msgRecvQueue.front(); cout << "弹出来的数据是" << command << endl; msgRecvQueue.pop_front(); }
未完