现在的位置: 首页 > 综合 > 正文

Windows多线程并发访问控制类

2013年03月19日 ⁄ 综合 ⁄ 共 1676字 ⁄ 字号 评论关闭

多线程的趋势已经不可阻挡,在并发算法不成熟或者存在先天排斥性的数据处理的时候,并发控制类就显得尤为重要,此处列出一个方便的通用类,避免重新发明轮子。
并发访问基类如下:

#ifndef _THREAD_SYNC_
#define _THREAD_SYNC_

#include <windows.h>

// 封装windows下临界区的类
// windows下临界区属于进程用户态变量(类似全局变量),是多线程互斥访问的不二选择
class CriticalSection
{
public:
	CriticalSection()
	{
		InitializeCriticalSection(&m_csLock);
	}

	inline void Enter()
	{
		EnterCriticalSection(&m_csLock);
	}

	inline void Leave()
	{
		LeaveCriticalSection(&m_csLock);
	}

	~CriticalSection()
	{
		DeleteCriticalSection(&m_csLock);
	}

private:
	CRITICAL_SECTION m_csLock;
};

/* 
具备多线程互斥访问功能的基类
设计成模板是为了使其可以为每一个派生自该类的子类维护一个互斥量数据
设计一个内部类AutoThreadSync是为了方便对子类中数据的加锁、解锁操作更加自动化
(采用C++理念中提倡的数据创建即初始化,销毁即释放的理念)
*/
template< typename T >
class MultiThreadSync
{
	friend class AutoThreadSync;

public:
	class AutoThreadSync
	{
	public:
		AutoThreadSync()
		{
			mSync.Enter();
		}

		~AutoThreadSync()
		{
			mSync.Leave();
		}
	};

	void ManualLock()
	{
		mSync.Enter();
	}

	void ManualUnLock()
	{
		mSync.Leave();
	}

private:
	static CriticalSection mSync;
};

template< typename T >
CriticalSection MultiThreadSync< T >::mSync;

#endif

测试代码如下:

#include <windows.h>
#include <vector>

#include "ThreadSync.h"

using namespace std;

// 测试用数据类
class DataMgr : public MultiThreadSync< DataMgr >
{
public:
	DataMgr()
	{
		m_vecAge.clear();
	}

	// 往容器中不断添加随机产生的数据
	void Add()
	{
		AutoThreadSync threadSync;
		int n = rand();
		m_vecAge.push_back(n);
	}

private:
	vector< int > m_vecAge;
};


// 全局的数据管理模块对象
DataMgr g_DataMgr;

// 线程功能函数,往同一个数据管理模块中添加数据
DWORD WINAPI ThreadFunc(LPVOID second)
{
	int nIndex = (int)second;

	while(true)
	{
		g_DataMgr.Add();
	}

	return 0;
}

int main()
{
	// 创建100个线程,同时往一个全局对象中添加数据,如果不加锁程序会出现崩溃
	// 关于容器多多线程的支持,可以google
	// STL容器仅承诺“支持并发读取,不支持并发写入”,之外一切并发操作均可能并发异常
	for (int i = 0; i < 100; i++)
	{
		HANDLE hThread;
		DWORD threadID;
		hThread = CreateThread(NULL, 0, ThreadFunc, (LPVOID)i, 0, &threadID);
		if (hThread)
		{
			printf("Launch thread %d\n", i + 1);
		}
	}

	while(true)
		;

	return EXIT_SUCCESS;
}

抱歉!评论已关闭.