在开发多线程程序时,常常碰到线程管理的问题。当有多种线程的时候,为了控制每个线程,编程工作也变得复杂。事实上,我们对线程的控制大多是相似的,所以把这些控制抽象出来,形成一个可复用的程序模块,将能大大提高开发效率和代码质量。
首先我们对线程的使用目的进行分析和归纳。一般来说,有如下几种:
1) 独立线程。执行一项在后台完成的工作,工作频率很低,线程的生命期里只完成一项任务。线程基本上不需要什么管理。
2) 定时线程。线程每隔一段时间,定时执行一定的功能,可能是查看某一状态,或输出某种信息。线程要设定时间间隔,并且需要显式地中止才会结束。
3) 守护线程。线程等待某事的发生,当事件发生时开始工作,完成后继续进行等待状态。因为事件发生的非常频繁时,使用守护线程以避免独立线程会带来的太多的线程开销。线程要能随时启动,也需要显式地中止才会结束。
所以线程管理需要完成以下功能:
1) 等待。当工作完成时,自动进入等待状态,而不是中止。
2) 定时执行。等待某一时间后,能自动执行。
3) 调用执行。当事件发生时,能继续执行。
4) 中止。正常地结束,把任务处理完,中止线程。
设计一个具有以上管理功能的线程并不困难,但为每一个线程都写一段这样的代码就显得很麻烦了,更何况这些代码其实都是类似的。为此,笔者设计了一个线程管理类,把线程的工作函数放入线程管理的框架内执行。线程的工作函数不再是线程的开始入口,而仅被作为一个函数被调用。
类的声明如下:
class CThreadMaster
{
public:
CThreadMaster(void);
~CThreadMaster(void);
typedef void (*WorkFuncType)(void * param);
enum CycleTimeEnum{ AlwaysWait = -1, AlwaysWork = 0};
void Start();
void Stop();
void WorkNow();
void Set(WorkFuncType function, void * parameter, int cycleTime);
void SetWorkFunction( WorkFuncType function );
void SetWorkParameter( void * parameter);
void SetCycleTime( int cycleTime );
unsigned long GetThreadId();
static unsigned __stdcall WorkThread( void * lpParameter );
protected:
enum ThreadCmd{ nothing = 0, stop};
ThreadCmd m_ThreadCmd;
HANDLE m_hThread;
HANDLE m_hEvent;
unsigned int m_ThreadId;
int m_CycleTime;
void * m_lpParameter;
WorkFuncType m_WorkFunction;
};
{
public:
CThreadMaster(void);
~CThreadMaster(void);
typedef void (*WorkFuncType)(void * param);
enum CycleTimeEnum{ AlwaysWait = -1, AlwaysWork = 0};
void Start();
void Stop();
void WorkNow();
void Set(WorkFuncType function, void * parameter, int cycleTime);
void SetWorkFunction( WorkFuncType function );
void SetWorkParameter( void * parameter);
void SetCycleTime( int cycleTime );
unsigned long GetThreadId();
static unsigned __stdcall WorkThread( void * lpParameter );
protected:
enum ThreadCmd{ nothing = 0, stop};
ThreadCmd m_ThreadCmd;
HANDLE m_hThread;
HANDLE m_hEvent;
unsigned int m_ThreadId;
int m_CycleTime;
void * m_lpParameter;
WorkFuncType m_WorkFunction;
};
function:工作函数的指针;
parameter:工作函数的参数;
cycleTime:工作函数的执行周期期,可以是一个正整数的时间值,单位为1/1000秒,也可以是如CycleTimeEnum定义的两个特殊值:
enum CycleTimeEnum{ AlwaysWait = -1, AlwaysWork = 0};
cycleTime的值为AlwaysWait表示执行完工作函数以后,线程一直等待,直到WorkNow函数被调用,或线程被Stop函数中止;
cycleTime的值为AlwaysWork表示不停地循环调用工作函数。
如果cycleTime为其它正值,那么执行完工作函数之后,等待cycleTime指定的时长并重新调用工作函数。如果在等待期间调用了WorkNow,那么工作函数将立刻被执行。
函数Start()、Stop()用来启动的中止线程,WorkNow()用来使线程进入工作状态,多次调用WorkNow不会影响工作状态。
使用这个类,我们只要把线程函数定义为WorkFuncType类型的静态函数,然后调用CThreadMaster类实例的Set函数设置该函数的指针、参数、和工作状态,就可以使用CThreadMaster提供的控制函数来管理线程了。线程所有的工作都会安全地开始,并优雅地结束。CThreadMaster实例销毁时,也会自动结束线程。
现把这个类的实现代码放到下面,以供参考, CThreadMaster.cpp:



























































































































