使用QWaitCondition实现一个简单的线程池

上篇文章主要讲了线程池的使用
Qt中的线程池QThreadPool
本篇文章使用Qt的条件变量 QWaitCondition ,实现一个简单的线程池
关于 QWaitCondition 的使用,可以参照 线程的互斥和同步(7)- Qt的条件变量QWaitCondition

先来说一下简单的思路,线程池初始化时创建一定数量的线程(8个) ,所有的线程处于挂起状态。
当任务添加到列表时,唤醒一个线程执行任务。如果当前未执行任务数>线程池中最大线程数时,等待有空闲的线程再执行。
这里定义了四个类来实现线程池:

  • CThreadPoolData : 数据类,存储任务队列,条件变量和互斥锁以及线程循环条件的存储
  • CThread :线程类,继承自 QThread ,线程池中的每个线程对象,重写了 run() 函数。
  • CRunnable : 任务类,同 QRunnable 。需要子类化 run() 函数。
  • CThreadPool :线程池类,管理多个线程对象。可以添加任务,唤醒线程执行。

完整代码下载:
https://github.com/douzhongqiang/threadCode/tree/master/CThreadPool


接下来看一下代码:
线程池类 CThreadPool 中的定义,头文件:

函数 addTask 为添加任务接口,m_threads 为线程数组,存储所有的线程对象。
m_poolData 表示需要用到的数据,它的定义如下:

线程池的实现:

构造函数中,创建了 QThread::idealThreadCount() 个线程,放入到了线程对象数组中,并开启所有线程。
析构函数中,唤醒所有的线程,并等待线程结束。变量 m_isRunning 是每个线程中,退出 while() 循环的控制变量。
addTask 函数,将任务存入到任务列表中,并唤醒一个线程执行。如果当前没有挂起的线程,该信号会被忽略。

CThread 是继承自 QThread 的线程类,它的头文件定义:

cpp文件:

run函数中,等待被唤醒,如果被唤醒,从任务队列中取出任务,并执行。

CRunnable 为任务基类,它的定义比较简单


接下来使用一个例子,测试一下这个线程池:
测试任务 TestTaskRunnable

头文件:

cpp文件

这里任务执行的内容比较简单,将全部变量 g_number 自增1,并打印线程ID。

main 函数中调用

因为这里添加任务时使用的带引用计数的智能指针,无需我们考虑内存释放的问题。

运行结果:
Number is 0, Thread Id is 0000000000004DF8
Number is 8, Thread Id is 0000000000004DF8
Number is 9, Thread Id is 0000000000004DF8
Number is 7, Thread Id is 0000000000000468
Number is 4, Thread Id is 00000000000034D4
Number is 2, Thread Id is 0000000000001680
Number is 10, Thread Id is 0000000000004DF8
Number is 13, Thread Id is 0000000000004DF8
Number is 14, Thread Id is 0000000000004DF8
Number is 12, Thread Id is 0000000000001680
Number is 15, Thread Id is 0000000000001680
Number is 11, Thread Id is 00000000000034D4
Number is 1, Thread Id is 0000000000003D80
Number is 5, Thread Id is 0000000000003168
Number is 3, Thread Id is 000000000000057C
Number is 16, Thread Id is 00000000000034D4
Number is 6, Thread Id is 0000000000004220
Number is 19, Thread Id is 0000000000001680
Number is 18, Thread Id is 0000000000003168
Number is 17, Thread Id is 0000000000004DF8

You May Also Like

About the Author: admin

喜欢编程、爱游戏,更爱生活。

发表评论

电子邮件地址不会被公开。