Linux学习之"线程的再封装"

先上代码,主要是线程类"CLThread":

头文件:

View Code
#ifndef CLTHREAD_H
#define CLTHREAD_H

#include <pthread.h>
#include "CLExecutive.h"
#include "CLStatus.h"
#include "CLEvent.h"

/*
CLThread代表了一个线程,该类对象的生存期,即线程的生存期

该类对象必须从堆中分配,且不必调用delete释放内存

构造函数中的bWaitForDeath用于指示是否需要等待新线程结束。默认
情况是不需要的。若需要则设置为true,并且需保证最后一定要调用
WaitForDeath函数,否则资源无法释放

Run、WaitForDeath函数如果返回成功,则只能调用一次。
*/
class CLThread : public CLExecutive
{
public:
/*
构造和析构函数出错时,会抛出字符串类型异常
*pExecutiveFunctionProvider参数必须是从堆中分配的
*/
explicit CLThread(CLExecutiveFunctionProvider *pExecutiveFunctionProvider);
CLThread(CLExecutiveFunctionProvider *pExecutiveFunctionProvider, bool bWaitForDeath);
virtual ~CLThread();

virtual CLStatus Run(void *pContext = 0);

virtual CLStatus WaitForDeath();

private:
static void* StartFunctionOfThread(void *pContext);

private:
void *m_pContext;

CLEvent m_EventForWaitingForNewThread;
CLEvent m_EventForWaitingForOldThread;

pthread_t m_ThreadID;

bool m_bWaitForDeath;
bool m_Flag;
};

#endif

增加一些成员变量及一个构造函数,稍后解释。
实现:

View Code
#include "CLThread.h"
#include "CLExecutiveFunctionProvider.h"
#include "CLEvent.h"
#include "CLLog.h"

CLThread::CLThread(CLExecutiveFunctionProvider *pExecutiveFunctionProvider) : CLExecutive(pExecutiveFunctionProvider)
{
m_pContext = 0;
m_bWaitForDeath = false;
m_Flag = false;
}

CLThread::CLThread(CLExecutiveFunctionProvider *pExecutiveFunctionProvider, bool bWaitForDeath) : CLExecutive(pExecutiveFunctionProvider)
{
m_pContext = 0;
m_bWaitForDeath = bWaitForDeath;
m_Flag = false;
}

CLThread::~CLThread()
{
}

CLStatus CLThread::Run(void *pContext)
{
if(m_Flag)
return CLStatus(-1, 0);

m_pContext = pContext;

int r = pthread_create(&m_ThreadID, 0, StartFunctionOfThread, this);
if(r != 0)
{
CLLog::WriteLogMsg("In CLThread::Run(), pthread_create error", r);
delete this;
return CLStatus(-1, 0);
}

m_Flag = true;

if(!m_bWaitForDeath)
{
r = pthread_detach(m_ThreadID);
if(r != 0)
CLLog::WriteLogMsg("In CLThread::Run(), pthread_detach error", r);
}

CLStatus s = m_EventForWaitingForNewThread.Wait();
if(!s.IsSuccess())
{
CLLog::WriteLogMsg("In CLThread::Run(), m_EventForWaitingForNewThread.Wait error", 0);
}

CLStatus s1 = m_EventForWaitingForOldThread.Set();
if(!s1.IsSuccess())
{
CLLog::WriteLogMsg("In CLThread::Run(), m_EventForWaitingForOldThread.Set error", 0);
}

return CLStatus(0, 0);
}

void* CLThread::StartFunctionOfThread(void *pThis)
{
CLThread *pThreadThis = (CLThread *)pThis;

void *pContext = pThreadThis->m_pContext;
pThreadThis->m_pContext = NULL;

CLStatus s = pThreadThis->m_EventForWaitingForNewThread.Set();
if(!s.IsSuccess())
{
CLLog::WriteLogMsg("In CLThread::StartFunctionOfThread(), m_pEventForThreadSynchronization.Set error", 0);
}

CLStatus s1 = pThreadThis->m_EventForWaitingForOldThread.Wait();
if(!s1.IsSuccess())
{
CLLog::WriteLogMsg("In CLThread::StartFunctionOfThread(), m_EventForWaitingForOldThread.Wait error", 0);
}

pThreadThis->m_pExecutiveFunctionProvider->RunExecutiveFunction(pContext);

if(!(pThreadThis->m_bWaitForDeath))
delete pThreadThis;

return 0;
}

CLStatus CLThread::WaitForDeath()
{
if(!m_bWaitForDeath)
return CLStatus(-1, 0);

if(!m_Flag)
return CLStatus(-1, 0);

int r = pthread_join(m_ThreadID, 0);
if(r != 0)
{
CLLog::WriteLogMsg("In CLThread::WaitForDeath(), pthread_join error", r);
return CLStatus(-1, 0);
}

delete this;
return CLStatus(0, 0);
}

m_bWaitForDeath:让用户指定他是否需要等待新线程死亡,并添加了与之相关的构造函数。

m_Flag:防止用户在一个CLThread对象上多次调用Run(),防止在没有Run()的情况下就WaitForDeath()
m_EventForWaitingForNewThread和m_EventForWaitingForOldThread:用于同步主线程和子线程,保证:1.“Run方法退出之前,新线程不会死亡”,2.“Run方法返回前,应保证新线程确实已经被创建”。用于避免由于在新线程先退出再WaitForDeath()而引发异常。

在Run()中,当新线程创建后,把m_Flag置为true;

若用户不选择等待线程结束(不会调用WaitForDeath()),则调用pthread_detach()使线程新线程进入detached状态,以便该线程运行结束后会自动释放所有资源。关于为什么要使其进入detached状态(包括其他状态),参见"百度百科pthread_detach"。

然后,调用CLEvent类型的m_EventForWaitingForNewThread的Wait()来等待新线程创建完成;在退出前,m_EventForWaitingForOldThread.Set()告诉新线程可以继续运行,执行具体的业务逻辑。退出后,即可调用WaitForDeath()等待新线程结束。

一单子线程运行到StartFunctionOfThread(),就意味着新线程的创建已经完成,此时,m_EventForWaitingForNewThread.Set()告诉主线程的Run()函数可以继续,自己则在m_EventForWaitingForOldThread上等待Run()发出的退出信号。

执行完具体业务逻辑后,子线程返回到StartFunctionOfThread()中,在退出前,如果用户选择子线程自行结束,则这是子线程最后释放资源的机会delete pThreadThis释放自己所占有的资源。

WaitForDeath()中,若用户没有选择m_bWaitForDeath或新线程尚未创建,直接退出;退出前,同StartFunctionOfThread()一样,释放自身资源。

posted @ 2011-10-22 21:26  lq0729  阅读(902)  评论(0编辑  收藏  举报