C++:线程池类的定义

功能介绍

此类实现了如下功能:
在程序启动时即创建若干个线程(即线程池),当有任务需要执行时,将需要执行的任务放入任务队列,唤醒一个空闲线程进行任务的处理,处理完任务后线程继续进入睡眠 状态。

类名 内容
CAutoLock 自动锁
CMutex 该类实现了互斥锁的封装
CTask 任务封装,ITask的实例
CTaskThread 任务线程类
CThread 线程类封装,实现了睡眠线程唤醒机制
ITask 接口类,定义了几个虚函数
ITaskThreadSink 任务线程槽接口,主要为了在启动任务前或任务结束后需要执行一些相关操作而实现

自动锁

/** @class CAutoLock
 * @brief 自动锁
 *
 * 该类实现了对CMutex类对象的自动上锁与解锁,它只提供了两个方法,构造与析构
 * 在构造函数里对CMutex类对象上锁,在析构函数里进行解锁
 */
class CAutoLock
{
public:
	/** @brief 构造函数,自动上锁 */
	CAutoLock(CMutex *pMutex)
	{
		m_pMutex = pMutex;
		m_pMutex->Lock();
	}
	
	/** @brief 析构函数,自动解锁 */
	virtual ~CAutoLock()
	{
		m_pMutex->Unlock();
	}

private:
	CMutex * m_pMutex;
};

#endif

互斥锁的封装

/** @class CMutex
 * @brief 该类实现了互斥锁的封装
 */
class CMutex
{
public:
	/** @brief 构造函数 */
	CMutex();
	/** @brief 析构函数 */
	virtual ~CMutex();

	/** @brief 上锁操作 
	 * @return 0-成功,非0-失败
	 */
	int Lock();

	/** @brief 解锁操作 
	 * @return 0-成功,非0-失败
	 */
	int Unlock();

	/** @brief 尝试上锁操作,非阻塞
	 * @return 0-成功,非0-失败
	 */
	int TryLock();

	/** @brief 获取互斥锁
	 * @return 返回互斥锁指针
	 */
	pthread_mutex_t * GetPthreadMutex() { return &m_mutex; }
	
protected:	

private:
	pthread_mutex_t    m_mutex;
};

任务的封装

#define  PRIORITY_LOW   1
#define  PRIORITY_HIGH  4

/** @class CTask
 * @brief 任务封装,ITask的实例
 */
class CTask : public ITask
{
public:
	CTask(int p = PRIORITY_LOW);
	virtual ~CTask();

	/** @brief 预执行任务 */
	virtual void PreExec();

	/** @brief 需要执行的任务 */
	virtual void Execute() = 0 ;

	/** @brief 执行后处理 */
	virtual void PostExec();

	/** @brief 获取当前任务优先级 
	 * @return 当前任务的优先级别
	 */
	virtual int   Priority(void);

	/** @brief 设备任务优先级 
	 * @param p - 任务优先级,从1到4为从低到高 
	 */
	virtual void  Priority(int p);

private:
	int   m_priority;
};

接口类

其中继承的ITask为:


/** @class ITask 任务封装接口
 * @brief 接口类,定义了几个虚函数
 */
class ITask
{
public:
	/** @brief 析构函数 */
    virtual ~ITask() { }
	/** @brief 预执行任务 */
    virtual void PreExec() { }
	/** @brief 执行主任务 */
    virtual void Execute() = 0;
	/** @brief 执行后收尾工作 */
    virtual void PostExec() { } 
	/** @brief 设置优先级 */
    virtual void Priority(int p) = 0;
	/** @brief 获取优先级 */
    virtual int Priority() = 0;
};

线程类封装

/** @class CTaskThread
 * @brief 任务线程类
 *
 * 该类的使用方法为:先创建一个ITask对象,并实现其需要执行的函数代码,
 * 需要实现的函数主要为:PreExec(), Execute(),PostExec(),
 * 接着通过调用SetTask()方法将ITask对象作为参数传入,使其作为线程需要执行的任务
 * 在SetTask()函数中会调用线程的SignalThread()函数唤醒线程以执行任务。
 * 在启动任务前,若设置了ITaskThreadSink对象,则会先执行其OnTaskStart()函数,
 * 在结束任务后,若设置了ITaskThreadSink对象,则会执行其OnTaskStop()函数
 */
class CTaskThread : public CThread
{
	public:
		/** @brief 构造函数
		 * @param pSink - 线程任务启动前或结束后需执行相关操作时,可传入此参数
		 */
		CTaskThread(ITaskThreadSink  *pSink = NULL);

		/** @brief 析构函数 */
		virtual ~CTaskThread();

		/** @brief 启动线程执行pTask中的任务,传入不同的ITask对象可以让线程执行不同的任务\n
		 * 执行完任务后,线程继续进入等待状态
		 * @param pTask - 需要执行的任务对象,会执行其PreExec(),Execute()和PostExec()函数
		 * @return 0 - 操作成功, 否则失败
		 * @note 返回0时并不代表任务执行一定正确,并且在执行完任务会,会删除pTask对象
		 */
		int  SetTask(ITask *pTask);		

		/** @brief 获取当前CTaskThread对象的地址
		 * @return 本对象地址
		 */
		unsigned long  GetTaskThreadId() const ;

	protected:
		virtual void ExecuteTask();

	private:
		ITaskThreadSink  *m_pSink;
		ITask  *m_pTask;	
		CMutex  m_cMutexTask;
		unsigned long m_nId;
};

其中继承CThread为:

/** @class CThread
 * @brief 线程类封装,实现了睡眠线程唤醒机制
 */
class CThread
{
public:
	/** @brief 构造函数, 条件变量在此时初始化 */
	CThread();

	/** @brief 析构函数 */
	virtual ~CThread();

protected:
	/** @brief 线程函数
	 *
	 * 在TheThread()线程函数中调用此函数,为执行任务循环的主体 
	 * 为保证线程只有一个实例在运行,在此函数开始执行前会先上锁保护。
	 * 直到此函数结束才释放锁,故在调用Start函数时需注意
	 */
	virtual void  Thread();

	/** @brief 执行任务函数,在线程被唤醒时执行的函数 */
	virtual void  ExecuteTask();

public:
	/** @brief 启动线程任务循环 */
	virtual int    Start();

	/** @brief 结束此线程,会等待线程退出 */
	virtual int    Kill();

	/** @brief 检查线程是否在运行
	 * @return true - 在运行,false - 未运行
	 */
	bool   IsRunning() { return m_bRunning; }	 	

protected:
	/** @brief 创建线程时的线程函数 */
	static void * TheThread(void *param);

	/** @brief 设置线程的运行状态 
	 * @param b true - 已运行, false - 未运行
	 */
	void   SetRunning(bool b);

	/** @brief 设置线程的结束标记 
	 * @param b - true 结束线程
	 */
	void   SetEndFlag(bool b);

	/** @brief 获取线程结束标记
	 * @return true - 线程已结束 false - 线程未结束
	 */
	bool   IsEndFlagSet() { return m_bEndFlag; }

	/** @brief 发送信号唤醒线程开始执行任务 */
	void   SignalThread();

private:
	pthread_t    m_hThread;	
	bool         m_bRunning;
	bool         m_bEndFlag;
	pthread_cond_t  m_Cond;
	CMutex       m_cMutexStatus;	
	CMutex       m_cMutexThread;
};

线程槽


/** @class ITaskThreadSink
 * @brief 任务线程槽接口,主要为了在启动任务前或任务结束后需要执行一些相关操作而实现
 */
class ITaskThreadSink
{
	public:
		/** @brief 析构函数 */
		virtual ~ITaskThreadSink() { }

		/** @brief 在启动任务前需执行的操作 */
		virtual int OnTaskStart(CTaskThread *thread) = 0;

		/** @brief 在任务执行完成后需执行的操作 */
		virtual int OnTaskStop(CTaskThread *thread) = 0;
};

发布了247 篇原创文章 · 获赞 93 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_33487044/article/details/99180874
今日推荐