c++多线程(十八) - windows临界区

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;
}

猜你喜欢

转载自blog.csdn.net/liyazhen2011/article/details/89810698