/** \file
* Thread.h,定义线程创建和停止接口,通过内联函数提供给其它模块使用
*
* \author Fzuim
*
* 版本历史
* \par 2014-7-7
*
*
*
*/
#pragma once
#include <process.h>
typedef unsigned int (WINAPI *THREAD_FUNC)(LPVOID lpThreadParameter);
class CThread
{
public:
CThread(THREAD_FUNC ThreadFunc,PVOID ThreadArg, int priority = THREAD_PRIORITY_NORMAL)
{
m_threadFunc = ThreadFunc;
m_threadArg = ThreadArg;
m_hThead = (HANDLE)_beginthreadex( NULL,
0,
(THREAD_FUNC)m_threadFunc,
ThreadArg,
CREATE_SUSPENDED,
(unsigned int *)&m_dwThreadID);
if(INVALID_HANDLE_VALUE != m_hThead)
{
SetThreadPriority(m_hThead, priority);
}
}
~CThread()
{
if(m_hThead && INVALID_HANDLE_VALUE != m_hThead)
{
::CloseHandle(m_hThead);
}
}
void Run()
{
if(m_hThead && INVALID_HANDLE_VALUE != m_hThead)
{
::ResumeThread(m_hThead);
}
}
void Stop()
{
if(NULL != m_hThead && INVALID_HANDLE_VALUE != m_hThead)
{
TerminateThread(m_hThead, 0);
CloseHandle(m_hThead);
m_hThead = NULL;
}
}
DWORD GetExitCode()
{
DWORD dwRet = 0;
::GetExitCodeThread(m_hThead,&dwRet);
return dwRet;
}
HANDLE m_hThead;
DWORD m_dwThreadID;
private:
THREAD_FUNC m_threadFunc;
PVOID m_threadArg;
};
此处我们创建线程采用的是_beginthreadex的方式,为什么不用CreateThread呢?理由如下:
CreateThread()和_beginthreadex()在Jeffrey的《Windows核心编程》中讲的很清楚,应当尽量避免使用CreateThread()。
事实上,_beginthreadex()在内部先为线程创建一个线程特有的tiddata结构,然后调用CreateThread()。在某些非线程安全的CRT函数中会请求这个结构。如果直接使用CreateThread()的话,那些函数发现请求的tiddata为NULL,就会在现场为该线程创建该结构,此后调用EndThread()时会引起内存泄漏。_endthreadex()可以释放由CreateThread()创建的线程,实际上,在它的内部会先释放由_beginthreadex()创建的tiddata结构,然后调用EndThread()。
因此,应当使用_beginthreadex()和_endthreadex(),而避免使用CreateThread()和EndThread()。当然_beginthread()和_endthread()也是应当避免使用的。