c++多线程(十八) - windows临界区
程序员文章站
2022-07-05 10:36:11
...
1. 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;
}
2.自动析构
EnterCriticalSection()和LeaveCriticalSection()必须成对使用。但是程序员很容易EnterCriticalSection()后忘记调用LeaveCriticalSection(),导致代码段长时间锁定。为了避免这个问题,设计一个资源管理类,在构造函数里调用EnterCriticalSection(),在析构函数里调用LeaveCriticalSection(),程序员再也不用担心资源释放的问题了。这个类的作用类似于c++11中的lock_guard。
#include<iostream>
#include<thread>
#include<list>
#include<windows.h>
using namespace std;
class CWinLock
{
public:
CWinLock(CRITICAL_SECTION *pCritical)
{
m_pCritical = pCritical;
EnterCriticalSection(m_pCritical); //进入临界区
}
~CWinLock()
{
LeaveCriticalSection(m_pCritical); //离开临界区
}
private:
CRITICAL_SECTION *m_pCritical; //windows临界区
};
class MsgManage
{
public:
MsgManage()
{
InitializeCriticalSection(&myWInsec);//初始化windows临界区
}
~MsgManage() {}
void InMsg()
{
for (int i = 0; i < 10000; i++)
{
cout << "插入元素: " << i << endl;
CWinLock winLock(&myWInsec);
myList.push_back(i);
}
}
bool outMsgProc(int &num)
{
CWinLock winLock(&myWInsec);
if (!myList.empty())
{
num = myList.front();
myList.pop_front();
return true;
}
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;
}