//(1)windows临界区 #include<iostream> #include<thread> #include<vector> #include<list> #include<mutex> #include<windows.h> #define _WINDOWS //定义一个开关 using namespace std; class A { public: A() { #ifdef _WINDOWS InitializeCriticalSection(&my_winsec); //用临界区之前要先初始化 #endif // _WINDOWS } public: //把收到的消息,入到一个队列中 void inMsgRecvQueue() { int i; for (i = 0; i < 100000; ++i) { cout << "push_back num = " << i << endl; //lock之后只能有一个线程可以对msgQueue队列做操作 #ifdef _WINDOWS EnterCriticalSection(&my_winsec); msgQueue.push_back(i); //数字i就是玩家的命令。 LeaveCriticalSection(&my_winsec); #else my_mutex.lock(); msgQueue.push_back(i); //数字i就是玩家的命令。 my_mutex.unlock(); #endif // } } bool outMsgProc(int& command) { #ifdef _WINDOWS EnterCriticalSection(&my_winsec); if (!msgQueue.empty()) { //消息不为空 command = msgQueue.front(); msgQueue.pop_front(); //移除首元素 LeaveCriticalSection(&my_winsec); return true; } else { LeaveCriticalSection(&my_winsec); return false; } #else my_mutex.lock(); if (!msgQueue.empty()) { //消息不为空 command = msgQueue.front(); msgQueue.pop_front(); //移除首元素 my_mutex.unlock(); return true; } else { my_mutex.unlock(); return false; } #endif } //把数据从消息队列中取出 void outMsgRecvQueue() { int i; int command = 0; for (i = 0; i < 100000; ++i) { int result = outMsgProc(command); if (result == true) { cout << "command = " << command << endl; } else { cout << "msgQueue is empty" << endl; } } } private: list<int> msgQueue; mutex my_mutex; //创建一个互斥量 #ifdef _WINDOWS CRITICAL_SECTION my_winsec; //windows下的临界区,非常类似C++的mutex #endif // _WINDOES }; 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)多次进入临界区试验 #include<iostream> #include<thread> #include<vector> #include<list> #include<mutex> #include<windows.h> #define _WINDOWS //定义一个开关 using namespace std; class A { public: A() { #ifdef _WINDOWS InitializeCriticalSection(&my_winsec); //用临界区之前要先初始化 #endif // _WINDOWS } public: //把收到的消息,入到一个队列中 void inMsgRecvQueue() { int i; for (i = 0; i < 100000; ++i) { cout << "push_back num = " << i << endl; //lock之后只能有一个线程可以对msgQueue队列做操作 #ifdef _WINDOWS EnterCriticalSection(&my_winsec); EnterCriticalSection(&my_winsec); //这是允许的,但是对应的离开也需要写两次 msgQueue.push_back(i); //数字i就是玩家的命令。 LeaveCriticalSection(&my_winsec); LeaveCriticalSection(&my_winsec); //如果这个没有的话,相当于还是一直加着锁。 #else my_mutex.lock(); //my_mutex.lock(); //会报错,和windows有区别 msgQueue.push_back(i); //数字i就是玩家的命令。 my_mutex.unlock(); #endif // } } bool outMsgProc(int& command) { #ifdef _WINDOWS EnterCriticalSection(&my_winsec); if (!msgQueue.empty()) { //消息不为空 command = msgQueue.front(); msgQueue.pop_front(); //移除首元素 LeaveCriticalSection(&my_winsec); return true; } else { LeaveCriticalSection(&my_winsec); return false; } #else my_mutex.lock(); if (!msgQueue.empty()) { //消息不为空 command = msgQueue.front(); msgQueue.pop_front(); //移除首元素 my_mutex.unlock(); return true; } else { my_mutex.unlock(); return false; } #endif } //把数据从消息队列中取出 void outMsgRecvQueue() { int i; int command = 0; for (i = 0; i < 100000; ++i) { int result = outMsgProc(command); if (result == true) { cout << "command = " << command << endl; } else { cout << "msgQueue is empty" << endl; } } } private: list<int> msgQueue; mutex my_mutex; //创建一个互斥量 #ifdef _WINDOWS CRITICAL_SECTION my_winsec; //windows下的临界区,非常类似C++的mutex #endif // _WINDOES }; 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; } //(3)自动析构技术 // std::lock_guard<std::mutex> //自动加锁和解锁 #include<iostream> #include<thread> #include<vector> #include<list> #include<mutex> #include<windows.h> #define _WINDOWS //定义一个开关 using namespace std; //自动加锁,自动释放锁的写法,类似与lock_guard的写法 class CWinLock { public: CWinLock(CRITICAL_SECTION* _my_winsec) :my_winsec(_my_winsec) { EnterCriticalSection(my_winsec); } ~CWinLock() { LeaveCriticalSection(my_winsec); } private: CRITICAL_SECTION* my_winsec; //windows下的临界区,非常类似C++的mutex }; class A { public: A() { #ifdef _WINDOWS InitializeCriticalSection(&my_winsec); //用临界区之前要先初始化 #endif // _WINDOWS } public: //把收到的消息,入到一个队列中 void inMsgRecvQueue() { int i; for (i = 0; i < 100000; ++i) { cout << "push_back num = " << i << endl; //lock之后只能有一个线程可以对msgQueue队列做操作 #ifdef _WINDOWS CWinLock clock(&my_winsec); //RAII的写法 msgQueue.push_back(i); //数字i就是玩家的命令。 #else std::lock_guard<std::mutex> lock_g(my_mutex); //自动加锁,自动释放锁。以{}为范围 //my_mutex.lock(); //my_mutex.lock(); //会报错,和windows有区别 msgQueue.push_back(i); //数字i就是玩家的命令。 //my_mutex.unlock(); #endif // } } bool outMsgProc(int& command) { #ifdef _WINDOWS EnterCriticalSection(&my_winsec); if (!msgQueue.empty()) { //消息不为空 command = msgQueue.front(); msgQueue.pop_front(); //移除首元素 LeaveCriticalSection(&my_winsec); return true; } else { LeaveCriticalSection(&my_winsec); return false; } #else my_mutex.lock(); if (!msgQueue.empty()) { //消息不为空 command = msgQueue.front(); msgQueue.pop_front(); //移除首元素 my_mutex.unlock(); return true; } else { my_mutex.unlock(); return false; } #endif } //把数据从消息队列中取出 void outMsgRecvQueue() { int i; int command = 0; for (i = 0; i < 100000; ++i) { int result = outMsgProc(command); if (result == true) { cout << "command = " << command << endl; } else { cout << "msgQueue is empty" << endl; } } } private: list<int> msgQueue; mutex my_mutex; //创建一个互斥量 #ifdef _WINDOWS CRITICAL_SECTION my_winsec; //windows下的临界区,非常类似C++的mutex #endif // _WINDOES }; 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; } //(4)recursive_mutex递归的独占互斥量 #include<iostream> #include<thread> #include<vector> #include<list> #include<mutex> #include<windows.h> //#define _WINDOWS //定义一个开关 using namespace std; //自动加锁,自动释放锁的写法,类似与lock_guard的写法 class CWinLock { public: CWinLock(CRITICAL_SECTION* _my_winsec) :my_winsec(_my_winsec) { EnterCriticalSection(my_winsec); } ~CWinLock() { LeaveCriticalSection(my_winsec); } private: CRITICAL_SECTION* my_winsec; //windows下的临界区,非常类似C++的mutex }; class A { public: A() { #ifdef _WINDOWS InitializeCriticalSection(&my_winsec); //用临界区之前要先初始化 #endif // _WINDOWS } public: //把收到的消息,入到一个队列中 void inMsgRecvQueue() { int i; for (i = 0; i < 100000; ++i) { cout << "push_back num = " << i << endl; //lock之后只能有一个线程可以对msgQueue队列做操作 #ifdef _WINDOWS CWinLock clock(&my_winsec); //RAII的写法 msgQueue.push_back(i); //数字i就是玩家的命令。 #else my_mutex.lock(); my_mutex.lock(); //会报错,和windows有区别 msgQueue.push_back(i); //数字i就是玩家的命令。 my_mutex.unlock(); my_mutex.unlock(); #endif // } } bool outMsgProc(int& command) { #ifdef _WINDOWS EnterCriticalSection(&my_winsec); if (!msgQueue.empty()) { //消息不为空 command = msgQueue.front(); msgQueue.pop_front(); //移除首元素 LeaveCriticalSection(&my_winsec); return true; } else { LeaveCriticalSection(&my_winsec); return false; } #else my_mutex.lock(); if (!msgQueue.empty()) { //消息不为空 command = msgQueue.front(); msgQueue.pop_front(); //移除首元素 my_mutex.unlock(); return true; } else { my_mutex.unlock(); return false; } #endif } //把数据从消息队列中取出 void outMsgRecvQueue() { int i; int command = 0; for (i = 0; i < 100000; ++i) { int result = outMsgProc(command); if (result == true) { cout << "command = " << command << endl; } else { cout << "msgQueue is empty" << endl; } } } private: list<int> msgQueue; //mutex my_mutex; //创建一个互斥量,是一个独占互斥量 //是一个递归的独占互斥量,在同一个线程内,可以多次lock,但也需要多次unlock,需要相对应 recursive_mutex my_mutex; //与windows中的CRITICAL_SECTION更像 #ifdef _WINDOWS CRITICAL_SECTION my_winsec; //windows下的临界区,非常类似C++的mutex #endif // _WINDOES }; 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; } //(5)带超时的互斥量std::timed_mutex和std::recursive_timed_mutex //try_lock_for() //等待一段时间 //try_lock_until() //未来的时间点 #include<iostream> #include<thread> #include<vector> #include<list> #include<mutex> #include<windows.h> //#define _WINDOWS //定义一个开关 using namespace std; class A { public: A() { #ifdef _WINDOWS InitializeCriticalSection(&my_winsec); //用临界区之前要先初始化 #endif // _WINDOWS } public: //把收到的消息,入到一个队列中 void inMsgRecvQueue() { int i; for (i = 0; i < 100000; ++i) { cout << "push_back num = " << i << endl; //lock之后只能有一个线程可以对msgQueue队列做操作 #ifdef _WINDOWS CWinLock clock(&my_winsec); //RAII的写法 msgQueue.push_back(i); //数字i就是玩家的命令。 #else if (my_mutex.try_lock_until(chrono::steady_clock::now()+100ms)) //等待100ms来判断是否拿到锁 { msgQueue.push_back(i); //数字i就是玩家的命令。 my_mutex.unlock(); } else { cout << "Do not get lock..." << endl; } #endif // } } bool outMsgProc(int& command) { #ifdef _WINDOWS EnterCriticalSection(&my_winsec); if (!msgQueue.empty()) { //消息不为空 command = msgQueue.front(); msgQueue.pop_front(); //移除首元素 LeaveCriticalSection(&my_winsec); return true; } else { LeaveCriticalSection(&my_winsec); return false; } #else my_mutex.lock(); if (!msgQueue.empty()) { //消息不为空 command = msgQueue.front(); msgQueue.pop_front(); //移除首元素 my_mutex.unlock(); return true; } else { my_mutex.unlock(); return false; } #endif } //把数据从消息队列中取出 void outMsgRecvQueue() { int i; int command = 0; for (i = 0; i < 100000; ++i) { int result = outMsgProc(command); if (result == true) { cout << "command = " << command << endl; } else { cout << "msgQueue is empty" << endl; } } } private: list<int> msgQueue; std::timed_mutex my_mutex; #ifdef _WINDOWS CRITICAL_SECTION my_winsec; //windows下的临界区,非常类似C++的mutex #endif // _WINDOES }; 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; }