C++线程类

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;
}
到此为止,我们就可以利用此线程类,以优雅的方式来设计更加复杂的多线程需求!





  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值