1.std::mutex
#include "stdafx.h"
#include<iostream>
#include<thread>
#include<mutex>
#include<list>
using namespace std;
//lock()和unlock()要成对使用。
//分析需要保护的代码段
class MsgManage
{
public:
MsgManage() {}
~MsgManage() {}
void InMsg()
{
for (int i = 0; i < 10000; i++)
{
cout << "插入元素: " << i << endl;
myMutex.lock();
myList.push_back(i);
myMutex.unlock();
}
}
bool outMsgProc(int &num)
{
myMutex.lock();
if (!myList.empty())
{
num = myList.front();
myList.pop_front();
myMutex.unlock();
return true;
}
myMutex.unlock();
return false;
}
void OutMsg()
{
for (int i = 0; i < 10000; i++)
{
int num;
bool result = outMsgProc(num);
if (result)
{
cout << "移除元素: " << num << endl;
}
else
{
cout << "消息队列为空" << endl;
}
}
}
private:
list<int> myList;
mutex myMutex;
};
int main()
{
MsgManage manage;
thread outMsg(&MsgManage::OutMsg, &manage);
thread inMsg(&MsgManage::InMsg, &manage);
inMsg.join();
outMsg.join();
return 0;
}
2.windows临界区
#include<iostream>
#include<thread>
#include<list>
#include<windows.h>
using namespace std;
class MsgManage
{
public:
MsgManage()
{
InitializeCriticalSection(&myWInsec);//初始化windows临界区
}
~MsgManage() {}
void InMsg()
{
for (int i = 0; i < 10000; i++)
{
cout << "插入元素: " << i << endl;
EnterCriticalSection(&myWInsec); //进入临界区
myList.push_back(i);
LeaveCriticalSection(&myWInsec); //离开临界区
}
}
bool outMsgProc(int &num)
{
EnterCriticalSection(&myWInsec); //进入临界区
if (!myList.empty())
{
num = myList.front();
myList.pop_front();
LeaveCriticalSection(&myWInsec); //离开临界区
return true;
}
LeaveCriticalSection(&myWInsec); //离开临界区
return false;
}
void OutMsg()
{
for (int i = 0; i < 10000; i++)
{
int num;
bool result = outMsgProc(num);
if (result)
{
cout << "移除元素: " << num << endl;
}
else
{
cout << "消息队列为空" << endl;
}
}
}
private:
list<int> myList;
CRITICAL_SECTION myWInsec; //windows临界区
};
int main()
{
MsgManage manage;
thread outMsg(&MsgManage::OutMsg, &manage);
thread inMsg(&MsgManage::InMsg, &manage);
inMsg.join();
outMsg.join();
return 0;
}
3.综合
#include<iostream>
#include<thread>
#include<mutex>
#include<list>
#include<windows.h>
using namespace std;
#define _WINDOWSJQ_
class MsgManage
{
public:
MsgManage()
{
#ifdef _WINDOWSJQ_
InitializeCriticalSection(&myWInsec);//初始化windows临界区
#endif
}
~MsgManage() {}
void InMsg()
{
for (int i = 0; i < 10000; i++)
{
cout << "插入元素: " << i << endl;
#ifdef _WINDOWSJQ_
EnterCriticalSection(&myWInsec); //进入临界区
myList.push_back(i);
LeaveCriticalSection(&myWInsec); //离开临界区
#else
myMutex.lock();
myList.push_back(i);
myMutex.unlock();
#endif
}
}
bool outMsgProc(int &num)
{
#ifdef _WINDOWSJQ_
EnterCriticalSection(&myWInsec); //进入临界区
if (!myList.empty())
{
num = myList.front();
myList.pop_front();
LeaveCriticalSection(&myWInsec); //离开临界区
return true;
}
LeaveCriticalSection(&myWInsec); //离开临界区
#else
myMutex.lock();
if (!myList.empty())
{
num = myList.front();
myList.pop_front();
myMutex.unlock();
return true;
}
myMutex.unlock();
#endif
return false;
}
void OutMsg()
{
for (int i = 0; i < 10000; i++)
{
int num;
bool result = outMsgProc(num);
if (result)
{
cout << "移除元素: " << num << endl;
}
else
{
cout << "消息队列为空" << endl;
}
}
}
private:
list<int> myList;
mutex myMutex;
#ifdef _WINDOWSJQ_
CRITICAL_SECTION myWInsec; //windows临界区
#endif
};
int main()
{
MsgManage manage;
thread outMsg(&MsgManage::OutMsg, &manage);
thread inMsg(&MsgManage::InMsg, &manage);
inMsg.join();
outMsg.join();
return 0;
}
4.总结
通过对windows临界区和mutex实例测试,总结如下差异:
- 同一个线程,相同的临界区,允许多次进入。
- 同一个线程,相同的mutex对象,不允许多次lock()/unlock()