C++:线程池类的定义
【摘要】
文章目录
功能介绍类自动锁互斥锁的封装任务的封装接口类线程类封装线程槽
功能介绍
此类实现了如下功能: 在程序启动时即创建若干个线程(即线程池),当有任务需要执行时,将需要执行的任务放入任务队列,唤醒一个空闲线程进行任务的处理,处理完任务后线程继续进入睡眠 状态。
类
类名内容CAutoLock自动锁CMutex该类实现了互斥锁的封装CTask任...
功能介绍
此类实现了如下功能:
在程序启动时即创建若干个线程(即线程池),当有任务需要执行时,将需要执行的任务放入任务队列,唤醒一个空闲线程进行任务的处理,处理完任务后线程继续进入睡眠 状态。
类
类名 | 内容 |
---|---|
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
互斥锁的封装
/** @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;
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
任务的封装
#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;
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
接口类
其中继承的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;
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
线程类封装
/** @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;
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
其中继承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;
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
线程槽
/** @class ITaskThreadSink
* @brief 任务线程槽接口,主要为了在启动任务前或任务结束后需要执行一些相关操作而实现
*/
class ITaskThreadSink
{
public:
/** @brief 析构函数 */
virtual ~ITaskThreadSink() { } /** @brief 在启动任务前需执行的操作 */
virtual int OnTaskStart(CTaskThread *thread) = 0; /** @brief 在任务执行完成后需执行的操作 */
virtual int OnTaskStop(CTaskThread *thread) = 0;
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
文章来源: xuesong.blog.csdn.net,作者:内核笔记,版权归原作者所有,如需转载,请联系作者。
原文链接:xuesong.blog.csdn.net/article/details/99180874
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)