간단한 Thread 클래스

#ifndef __THREAD_H__
#define __THREAD_H__

class CThread
{
public:
	/*
	 *	Info: Default Constructor
	 */
	CThread()
	{ 
		m_pThreadFunc = CThread::EntryPoint; // Can call Detach() also.
	}

	/*
	 *	Info: Plug Constructor
	 *
	 *	Use this to migrate/port existing worker threads to objects immediately
	 *  Although you lose the benefits of ThreadCTOR and ThreadDTOR.
	 */
	CThread(LPTHREAD_START_ROUTINE lpExternalRoutine)
	{
		Attach(lpExternalRoutine);
	}

	/*
	 *	Info: Default Destructor
	 *
	 *	I think it is wise to destroy the thread even if it is running,
	 *  when the main thread reaches here.
	 */
	virtual ~CThread()
	{
		if ( m_ThreadCtx.m_hThread )
			Stop(true);
	}
	/*
	 *	Info: Starts the thread.
	 *	
	 *	This function starts the thread pointed by m_pThreadFunc with default attributes
	 */
	DWORD Start( void* arg = NULL )
	{
		m_ThreadCtx.m_pUserData = arg;
		m_ThreadCtx.m_hThread = CreateThread(NULL, 0, m_pThreadFunc, this, 0, &m_ThreadCtx.m_dwTID);
		m_ThreadCtx.m_dwExitCode = (DWORD)-1;

		return GetLastError();
	}

	/*
	 *	Info: Stops the thread.
	 *	
	 *	This function stops the current thread. 
	 *	We can force kill a thread which results in a TerminateThread.
	 */
	DWORD Stop ( bool bForceKill = false )
	{
		if ( m_ThreadCtx.m_hThread )
		{
			GetExitCodeThread(m_ThreadCtx.m_hThread, &m_ThreadCtx.m_dwExitCode);

			if ( m_ThreadCtx.m_dwExitCode == STILL_ACTIVE && bForceKill )
				TerminateThread(m_ThreadCtx.m_hThread, DWORD(-1));

			m_ThreadCtx.m_hThread = NULL;
		}

		return m_ThreadCtx.m_dwExitCode;
	}

	/*
	 *	Info: Starts the thread.
	 *	
	 *	This function starts the thread pointed by m_pThreadFunc with default attributes
	 */
	DWORD GetExitCode() const 
	{ 
		if ( m_ThreadCtx.m_hThread )
			GetExitCodeThread(m_ThreadCtx.m_hThread, (LPDWORD)&m_ThreadCtx.m_dwExitCode);
		return m_ThreadCtx.m_dwExitCode;
	}

	/*
	 *	Info: Attaches a Thread Function
	 *	
	 *	Used primarily for porting but can serve in developing generic thread objects
	 */
	void Attach( LPTHREAD_START_ROUTINE lpThreadFunc ){
		m_pThreadFunc = lpThreadFunc;
	}

	/*
	 *	Info: Detaches the Attached Thread Function
	 *	
	 *	Detaches the Attached Thread Function, If any.
	 *	by resetting the thread function pointer to EntryPoint1
	 */
	void  Detach( void ){
		m_pThreadFunc = CThread::EntryPoint; 
	}

protected:

	/*
	 *	Info: DONT override this method.
	 *	
	 *	This function is like a standard template. 
	 *	Override if you are sure of what you are doing.
	 */
	static DWORD WINAPI EntryPoint( LPVOID pArg)
	{
		CThread *pParent = reinterpret_cast<CThread*>(pArg);

		pParent->ThreadCtor();

		pParent->Run( pParent->m_ThreadCtx.m_pUserData );

		pParent->ThreadDtor();

		return STILL_ACTIVE;
	}
	
	/*
	 *	Info: Override this method.
	 *	
	 *	This function should contain the body/code of your thread.
	 *	Notice the signature is similar to that of any worker thread function
	 *  except for the calling convention.
	 */
	virtual DWORD Run( LPVOID /* arg */ )
	{ return m_ThreadCtx.m_dwExitCode; }

	/*
	 *	Info: Constructor-like function. 
	 *	
	 *	Will be called by EntryPoint before executing the thread body.
	 *  Override this function to provide your extra initialization.
	 *
	 *  NOTE: do not confuse it with the classes constructor
	 */
	virtual void ThreadCtor(){	}

	/*
	 *	Info: Destructor-like function. 
	 *	
	 *	Will be called by EntryPoint after executing the thread body.
	 *  Override this function to provide your extra destruction.
	 *
	 *  NOTE: do not confuse it with the classes constructor
	 */
	virtual void ThreadDtor(){	}
		
private:
	/*
	 *	Info: Thread Context Inner Class
	 *	
	 *	Every thread object needs to be associated with a set of values.
	 *	like UserData Pointer, Handle, Thread ID etc.
	 *  
	 *  NOTE: This class can be enhanced to varying functionalities
	 *		  eg.,
	 *				* Members to hold StackSize
	 *				* SECURITY_ATTRIBUTES member.
	 */
	class CThreadContext
	{
	public:
		CThreadContext(){
			memset(this, 0, sizeof(this));
		}

		/*
		 *	Attributes Section
		 */
	public:
		HANDLE m_hThread;					//	The Thread Handle
		DWORD  m_dwTID;						//	The Thread ID
		LPVOID m_pUserData;						//	The user data pointer
		LPVOID m_pParent;					//	The this pointer of the parent CThread object
		DWORD  m_dwExitCode;				//	The Exit Code of the thread
	};

	/*
	 *	Attributes Section
	 */
protected:
	/*
	 *	Info: Members of CThread
	 */
	CThreadContext			m_ThreadCtx;	//	The Thread Context member
	LPTHREAD_START_ROUTINE	m_pThreadFunc;	//	The Worker Thread Function Pointer
};

#endif //__THREAD_H__

 References: http://blog.csdn.net/netanimals/article/details/6657839 http://blog.csdn.net/xieqidong/article/details/4132014 http://www.cppblog.com/API/archive/2011/04/24/141563.html http://www.cppblog.com/true/archive/2009/01/19/72306.html

좋은 웹페이지 즐겨찾기