欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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