简单实用的线程管理类

来源:互联网 发布:圣水收集器升级数据 编辑:程序博客网 时间:2024/05/18 02:18
在开发多线程程序时,常常碰到线程管理的问题。当有多种线程的时候,为了控制每个线程,编程工作也变得复杂。事实上,我们对线程的控制大多是相似的,所以把这些控制抽象出来,形成一个可复用的程序模块,将能大大提高开发效率和代码质量。
首先我们对线程的使用目的进行分析和归纳。一般来说,有如下几种:
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;        
};
函数void Set(WorkFuncType function, void * parameter, int cycleTime);用来设置线程的工作函数、工作参数、和工作周期,参数如下:
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:
#include <process.h>
#include 
". hreadmaster.h"
 
CThreadMaster::CThreadMaster(
void)
{
     m_ThreadCmd 
= nothing; 
 
     m_hThread 
= NULL;
     m_hEvent 
= CreateEvent(NULL, FALSE, TRUE, NULL);
    
     m_ThreadId 
= 0;
 
     m_CycleTime 
= AlwaysWork;
     m_WorkFunction 
= NULL; 
     m_lpParameter 
= NULL;
}

 
CThreadMaster::
~CThreadMaster(void)
{
     Stop();
     CloseHandle(m_hEvent);
}

 
void CThreadMaster::Start()
{
     
if (m_ThreadId!=0)
         
return;
 
     m_ThreadCmd 
= nothing;
     m_hThread 
= (HANDLE)_beginthreadex(NULL,0, WorkThread, (void *)this0&m_ThreadId);
}

 
void CThreadMaster::Stop()
{
     
if (m_ThreadId==0)
         
return;
 
     m_ThreadCmd 
= stop;
     WorkNow();
     WaitForSingleObject(m_hThread, INFINITE);
     m_ThreadCmd 
= nothing;
     m_ThreadId 
= 0;
     m_hThread 
= NULL;
}

 
void CThreadMaster::WorkNow()
{
     
if (m_hThread==0)
     
{
         Start();
         SetEvent(m_hEvent);
     }
else
         SetEvent(m_hEvent);
}

 
unsigned CThreadMaster::WorkThread( 
void * lpParameter )
{
     CThreadMaster 
* pThis = (CThreadMaster*) lpParameter;
     
if (pThis==NULL)
         
return -1;
     
for(;;)
     
{
         
if (pThis->m_CycleTime > AlwaysWork)
              WaitForSingleObject(pThis
->m_hEvent, pThis->m_CycleTime);
         
else if (pThis->m_CycleTime<=AlwaysWait)
              WaitForSingleObject(pThis
->m_hEvent, INFINITE);
 
         
if (pThis->m_ThreadCmd==stop)
              
return 0;
 
         
if (pThis->m_WorkFunction!=NULL)
         
{
              
try{          
                   (
*pThis->m_WorkFunction)(pThis->m_lpParameter);
              }
catch (...){
              }

         }

     }

 
     
return -2;
}

 
void CThreadMaster::Set(WorkFuncType function, void * parameter, int cycleTime)
{
     m_WorkFunction     
= function;
     m_lpParameter 
= parameter;
     m_CycleTime        
= cycleTime;
}

 
void CThreadMaster::SetWorkFunction( WorkFuncType function )
{
     m_WorkFunction 
= function;
}

 
void CThreadMaster::SetWorkParameter( void * parameter)
{
     m_lpParameter 
= parameter;
}

 
void CThreadMaster::SetCycleTime( int cycleTime )
{
     m_CycleTime 
= cycleTime;
}

 
unsigned 
long CThreadMaster::GetThreadId()
{
     
return m_ThreadId;
}

 
原创粉丝点击