我的元件之執行緒類

LiuYinChina發表於2013-01-31
上一篇,我說到了 OwnerPolicy 很重要,究竟它有什麼樣的表現呢?請看下面,Thread 類的實現。

//	--------------------------------------------------------------
//	
//	Copyright (C) 2009 - All Rights Reserved.
//	
//	Author:		LiuYin
//	File:		Thread
//	Version: 	1.0
//	Date: 		2009-8-10
//	
//	Purpose:	
//	
//	--------------------------------------------------------------

#ifndef Thread_H
#define Thread_H

//////////////////////////////////////////////////////////////////////////

#include <WTypes.h>
#include <Process.h>

//////////////////////////////////////////////////////////////////////////

#include "OwnerPolicy.h"

//////////////////////////////////////////////////////////////////////////

template <class Owner>
class ThreadT	:	public OwnerPolicy<Owner>
{
	typedef ThreadT<Owner> This;

	//////////////////////////////////////////////////////////////////////////

	struct ThreadParam
	{
		This *pThis;
		LONG lCount;
	};

	//////////////////////////////////////////////////////////////////////////

public:
	ThreadT()
		:	m_hEventExit(NULL), 
			m_lThreadCount(0)
	{
		m_hEventExit = CreateEvent(NULL, TRUE, FALSE, NULL);
	}
	~ThreadT()
	{
		Stop();

		if (m_hEventExit != NULL) {
			CloseHandle(m_hEventExit);
			m_hEventExit = NULL;
		}
	}

	DWORD Start(DWORD dwCount)
	{
		const DWORD MAX_COUNT_ONE_TIME = 128;

		if (m_hEventExit == NULL) {
			return 0;
		}

		dwCount = ((dwCount > 0) && (dwCount < MAX_COUNT_ONE_TIME)) ? dwCount : MAX_COUNT_ONE_TIME;

		ThreadParam threadParam;
		threadParam.pThis	= this;
		threadParam.lCount	= dwCount;

		DWORD dwCreate = 0;
		HANDLE hThread[MAX_COUNT_ONE_TIME] = { 0 };
		for (DWORD i=0; i<dwCount; ++i) {
			hThread[i] = (HANDLE) _beginthreadex(NULL, 0, ThreadT::_SvcBase, &threadParam, 0, NULL);
			if (hThread[i] != NULL) {
				++dwCreate;
			}
			else {
				InterlockedDecrement(&(threadParam.lCount));
			}
		}

		while (InterlockedCompareExchange(&(threadParam.lCount), 0, 0) > 0) {
			Sleep(0);
		}

		for (DWORD i=0; i<dwCount; ++i) {
			if (hThread[i] == NULL) {
				continue;
			}

			CloseHandle(hThread[i]);
			hThread[i] = NULL;
		}

		return dwCreate;
	}

	VOID Stop()
	{
		SetEvent(m_hEventExit);
		while (InterlockedCompareExchange(&m_lThreadCount, 0, 0) > 0) {
			Sleep(0);
		}
		ResetEvent(m_hEventExit);
	}

private:
	static unsigned __stdcall _SvcBase(LPVOID pParam)
	{
		ThreadParam *pThreadParam = static_cast<ThreadParam *>(pParam);
		pThreadParam->pThis->Svc(pThreadParam);
		return 0xDead;
	}

	VOID Svc(ThreadParam *pThreadParam)
	{
		InterlockedIncrement(&m_lThreadCount);
		InterlockedDecrement(&(pThreadParam->lCount));

		Owner *pOwner = this->owner();
		if (pOwner == NULL) {
			goto Exit;
		}

		pOwner->Svc(this, m_hEventExit);
	Exit:
		InterlockedDecrement(&m_lThreadCount);
	}

private:
	HANDLE m_hEventExit;

	LONG m_lThreadCount;
};

//////////////////////////////////////////////////////////////////////////

#endif

示例用法如下:

#include <stdio.h>

#include "Thread.h"

//////////////////////////////////////////////////////////////////////////

class YourClass
{
	typedef ThreadT<YourClass> CThread;

public:
	YourClass()
	{
		m_threadA.owner(this);
		m_threadB.owner(this);
	}
	VOID Start()
	{
		m_threadA.Start(1);
		m_threadB.Start(2);
	}
	VOID Svc(CThread *pThread, HANDLE hEventExit)
	{
		if (pThread == &m_threadA) {
			while (TRUE) {
				if (WaitForSingleObject(hEventExit, 100) != WAIT_TIMEOUT) {
					break;
				}

				printf("This is thread A!\n");
			}
		}
		if (pThread == &m_threadB) {
			while (TRUE) {
				if (WaitForSingleObject(hEventExit, 100) != WAIT_TIMEOUT) {
					break;
				}

				OutputDebugString("This is thread B!\n");
			}
		}
	}
	VOID Stop()
	{
		m_threadA.Stop();
		m_threadB.Stop();
	}

private:
	CThread m_threadA;
	CThread m_threadB;
};

//////////////////////////////////////////////////////////////////////////

int main()
{
	YourClass yourClass;
	yourClass.Start();
	Sleep(1000 * 4);
	yourClass.Stop();
	return 0;
}

看到了嗎?這樣我的 Thread 類,重用性就非常高了,因為它和其他具體的類,其實沒有一點關係。如果我要在其他的類裡使用多執行緒也只用增加介面 Svc 及少量程式碼就可以了。利用模板,我們消除了它和其他類的聯絡,唯一的聯絡只在於 YourClass 中的 Svc 和 Thread 的 Start 及 Stop 介面。

相關文章