C++线程类
1.Runnable基类
纯虚的公共执行接口Run,要求派生类实现此方法的定义。
#ifndef _H_RUNNABLE_H_
#define _H_RUNNABLE_H_
class Runnable
{
public:
//虚析构 为了继承的完整析构
virtual ~Runnable() {};
//纯虚通用执行接口
virtual void Run() = 0;
};
#endif
2.CThread通用线程类
派生至Runnable类,并提供了对windows原生API的封装实现。
#ifndef _H_CTHREAD_H_
#define _H_CTHREAD_H_
#include <Windows.h>
#include <string>
#include <process.h>
#include "Runnable.h"
class CThread
:public Runnable
{
public:
CThread(Runnable* pRunnable = NULL);
virtual ~CThread();
/**
启动线程
@arg bSuspend 启动时是否挂起
**/
bool Start(bool bSuspend = false);
/**
执行体
**/
virtual void Run();
/**
主调线程等待
**/
void Join(int timeout = -1);
/**
取消挂起
**/
void Resume();
/**
挂起线程
PS:由于多线程的异步特性导致线程执行位置的不确定 勿轻易Suspend 否则会有造成死锁的可能或其他诡异的问题
**/
void Suspend();
/**
终止线程
@arg exitCode 退出代码
PS:最好的结束线程的方式是线程执行体自返回 勿轻易Terminate 否则会有造成死锁的可能或其他诡异的问题
**/
void Terminate(unsigned int exitCode);
/**
获取线程ID
**/
unsigned int ThreadID() const;
private:
/**
静态的线程入口
因为C++运行库的线程创建API对线程执行体函数签名有要求
故设定此静态函数转接入口执行体
**/
static unsigned int __stdcall StaticThreadFunc(void* param);
private:
HANDLE m_handle; //线程句柄
unsigned int m_threadID; //线程ID
Runnable* m_pRunnale; //线程的任务指针
volatile bool m_bRun; //线程是否运行
};
CThread::CThread( Runnable* pRunnable /*= NULL*/ )
:m_pRunnale(pRunnable)
,m_bRun(false)
{
NULL;
}
CThread::~CThread()
{
NULL;
}
bool CThread::Start( bool bSuspend /*= false*/ )
{
if (m_bRun)
{
return true;
}
// 此处用C++运行库的线程创建API而非windows系统的API CreateThread是有一堆理由的 请君自查之。
if (bSuspend)
{
m_handle = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, StaticThreadFunc, this, CREATE_SUSPENDED, &m_threadID));
}
else
{
m_handle = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, StaticThreadFunc, this, 0, &m_threadID));
}
m_bRun = (NULL != m_handle);
return m_bRun;
}
void CThread::Run()
{
if (NULL == m_handle || !m_bRun)
{
return;
}
if (NULL != m_pRunnale)
{
m_pRunnale->Run();
}
m_bRun = false;
}
void CThread::Join( int timeout /*= -1*/ )
{
if (NULL == m_handle || !m_bRun)
{
return;
}
if (timeout < 0)
{
timeout = INFINITE;
}
::WaitForSingleObject(m_handle, timeout);
}
void CThread::Resume()
{
if (NULL == m_handle || !m_bRun)
{
return;
}
::ResumeThread(m_handle);
}
void CThread::Suspend()
{
if (NULL == m_handle || !m_bRun)
{
return;
}
::SuspendThread(m_handle);
}
void CThread::Terminate(unsigned int exitCode)
{
if (NULL == m_handle || !m_bRun)
{
return;
}
::TerminateThread(m_handle, exitCode);
}
unsigned int CThread::ThreadID() const
{
return m_threadID;
}
unsigned int __stdcall CThread::StaticThreadFunc( void* param )
{
CThread* pt = reinterpret_cast<CThread*>(param);
if (pt)
{
pt->Run();
}
return 0;
}
#endif
到此为止,一个完整的C++线程类就完成了。下面来一点场景代码测试下,以便展示如何运用之!
3.测试代码
首先,定义一个可执行的任务类。当然,可以在其Run方法中写任何你需要做的逻辑。
#include <iostream>
#include "CThread.h"
using namespace std;
class Printer
: public Runnable
{
public:
void Run()
{
std::cout << "Hello World" << std::endl;
}
};
int main(int argc, char* argv[])
{
{
// 创建打印任务对象
Printer nomalPrinter;
//创建执行打印任务的线程对象
CThread nomalThread(&nomalPrinter);
//启动线程
nomalThread.Start();
//主线程等待线程完毕
nomalThread.Join();
}
system("pause");
return 0;
}
到此为止,我们就可以利用此线程类,以优雅的方式来设计更加复杂的多线程需求!