一、QThreadPool线程池的作用
QThreadPool 类管理 QThreads 的集合,用于管理、调度和回收单个 QThread 对象的线程池,另外QThreadPool实现了线程对象的最大复用,以帮助降低使用线程的程序中的线程创建和释放成本。
它提供了一种方便的方式来执行和管理 QRunnable 或 QThread 对象,并控制并发执行的线程数量。
线程的创建和销毁是有性能开销的,当我们有少量业务需要处理时,我们可以放到线程中完成,甚至可以多开几个线程并行处理。
二、QThreadPool线程池的原理
当处理海量数据时无法无限地开线程,因为CPU的性能是有限的,每个线程好比一个处理时间片,多个线程之间切换处理,CPU线程上下文来回切换,这个也是需要消耗时间的。
所以,当线程数量到达一定数量后,消耗在线程切换的时间会大于实际线程处理业务的时间,这时处理的最佳线程数则到达了最大值。
一般来讲,我们可以认为,最佳性能线程数==CPU逻辑核心数量,比如CPU是4核8线程,那么开8个线程可以达到性能最佳。
一般电脑是开启超线程的,也就是4核可以模拟出8个逻辑核,故称4核8线程。
最佳线程数参考链接
QThreadPool线程池默认最大线程数,也是CPU逻辑Core的数量。
总结:QTreadPool线程池的作用相当于管家,把线程丢进线程池中QThreadPool会自动管理现成的创建、调度、回收、复用等操作,有效避免了线程创建数量大于最佳数量同时能充分利用CPU资源。
三、QThreadPool线程池的使用
每个Qt应用程序都有一个全局QThreadPool对象,可以通过调用globalInstance()来访问该对象。
要使用其中一个 QThreadPool 线程,需要子类化 QRunnable 并实现 run() 虚函数。然后创建该类的对象并将其传递给 QThreadPool::start()。QThreadPool 默认自动删除 QRunnable。
3.1 QThreadPool两种启动线程方式
3.1.1 全局线程池
每个 Qt 应用程序都有一个全局 QThreadPool 对象,可以通过调用 globalInstance() 来访问它。
示例:
class HelloWorldTask : public QRunnable
{
void run() override
{
qDebug() << "Hello world from thread" << QThread::currentThread();
}
};
HelloWorldTask *hello = new HelloWorldTask();
// QThreadPool takes ownership and deletes 'hello' automatically
QThreadPool::globalInstance()-><