(1)windows临界区
(2)多次进入临界区实验
(3)自动析构技术
(4)recursive_mutex递归的独占互斥量
(5)带超时的互斥量std::timed_mutex和std::recursive_timed_mutex
#include <thread>
#include <windows.h>
#define __WINDOWS__
class A
{
public:
//把收到的消息放到一个队列中
void inMsgRecvQueue() //unlock()
{
for(int i=0;i<10000;++i)
{
cout<<"inMsgRecvQueue():"<<i<<endl;
#ifdef __WINDOWS__
EnterCriticalSection(&my_winsec);//获取锁,进入临界区
//Windows在同一个线程中,同一个临界区变量,可以多次进入临界区(两次加锁),但是需要(两次解锁)多次离开临界区
EnterCriticalSection(&my_winsec);
msgRecvQueue.push_back(i);
LeavCriticalSection(&my_winsec);//解锁,离开临界区
LeavCriticalSection(&my_winsec);
#else
std::unique_lock<std::mutex> lguard1(my_mutex1); //linux中mutex是不可以lock两次的
msgRecvQueue.push_back(i);//假设这个数字就是收到的命令,把他加入到队列中
//代码处理。。。
#endif
}
return ;
}
bool outMsgProc(int &command)
{ //双重锁定,双重检查
#ifdef __WINDOWS__
if(!msgRecvQueue.empty())
{ //添加这个双重锁定是因为每次不管是不是空都加锁然后再释放效率低,这样可以避免每次都加锁
EnterCriticalSection(&my_winsec);//获取锁
if(!msgRecvQueue.empty())
{
command = msgRecvQueue.front();//返回第一个元素,但不检查元素是否存在
msgRecvQueue.pop_front();//移除第一个元素
LeavCriticalSection(&my_winsec);//放开锁
return true;
}
}
#else
if(!msgRecvQueue.empty())
{ //添加这个双重锁定是因为每次不管是不是空都加锁然后再释放效率低,这样可以避免每次都加锁
std::unique_lock<std::mutex> lguard1(my_mutex1);
if(!msgRecvQueue.empty())
{
command = msgRecvQueue.front();//返回第一个元素,但不检查元素是否存在
msgRecvQueue.pop_front();//移除第一个元素
return true;
}
}
#endif
return false;
}
//把数据从消息队列中取出线程
void outMsgRecvQueue()
{
int command =0;
for(int i=0;i<10000;++i)
{
bool result=outMsgProc(command);
if(result==true)
{
cout<<"outMsgRecvQueue()执行,取出一个元素"<<command<<endl;
//对消息处理
}
else
{
//消息队列为空
sleep(100);
cout<<"outMsgRecvQueue()执行,但是消息队列为空"<<i<<endl;
}
}
cout<<"end"<<endl;
}
A()
{
#ifdef __WINDOWS__
InitializeCriticalSection(&my_winsec);//用临界区之前需要初始化
#endif
}
private:
std::list<int> msgRecvQueue;//容器(消息队列)专门用于代表玩家发送的命令
std::mutex my_mutex1;//创建了一个互斥量
std::mutex my_mutex2;//创建了一个互斥量
#ifdef __WINDOWS__
CRITICAL_SECTION my_winsec;//windows中的临界区,类似linux中的mutex
#endif
};
int main()
{ //windows临界区
//自动析构技术
A myobja;
std::thread my_out_Thread(&A::outMsgRecvQueue,&myobja);//outMsgRecvQueue为起始函数的线程
std::thread my_in_Thread(&A::inMsgRecvQueue,&myobja);//inMsgRecvQueue为起始函数的线程
outMsgRecvQueue.join();
inMsgRecvQueue.join();
cout<<"主线程收尾,正常退出"<endl;
return 0;
}