Qt多线程 — QThreadPool 线程池
一、简介
ThreadPool用于管理和回收单个QThread对象,目的是减少使用线程的应用程序中的创建线程的成本。每个Qt应用程序都包含一个全局的QThreadPool对象,可以调用globalInstance()来访问这个全局的QThreadPool对象。
二、使用方法
使用QThreadPool线程,需按照以下4个步骤:
(1)继承QRunnable。
(2)重载并实现run()虚函数。
(3)创建该类的一个对象。
(4)将创建的对象传递给QThreadPool::start()。
例如以下代码片段:
//【1】继承QRunnable,定义MyTask类
class MyTask : public QRunnable
{
//【2】重载并实现run()虚函数
void run() override
{
qDebug() << "I'm iriczhao!!!" << QThread::currentThread();
}
};
//【3】创建MyTask类的对象my_task
MyTask *my_task = new MyTask();
//【4】将创建的对象传递给QThreadPool::start
QThreadPool::globalInstance()->start(my_task);
三、QThreadPool的成员函数
(3-1)设置自动删除标志【setAutoDelete】
默认情况下,QThreadPool会自动删除QRunnable。使用QRunnable::setAutoDelete()来更改自动删除标志。
注意:这个标志必须在调用QThreadPool::start()之前设置。在QThreadPool::start()之后调用setAutoDelete函数将出现未定义的行为。
QThreadPool支持在QRunnable::run()中调用tryStart(this)来多次执行同一个QRunnable。如果autoDelete被启用,QRunnable将在最后一个线程退出run函数时被删除。在启用autoDelete条件下,使用同一个QRunnable对象多次调用start()会创建一个竞争条件(在开发中不建议这样使用)。
(3-2)设置线程超时时间【setExpiryTimeout】
在一定时间内未使用的线程将过期(超时时间为30000毫秒(30秒)),Qt中使用expiryTimeout来描述该参数。这个参数可以使用setExpiryTimeout()函数更改。当超时时间设置为负数时将禁用线程过期机制。
在expiryTimeout毫秒内未使用的线程被认为已经过期并将退出。这些线程将在需要时再重新启动。默认的expiryTimeout是30000毫秒(30秒)。如果expiryTimeout为负值,则新创建的线程不会过期,例如:在线程池销毁之前,线程不会退出。
(3-3)设置线程池的最大线程数【setMaxThreadCount】
- 调用
maxThreadCount()来查询线程池中使用的最大线程数。 - 可以使用setMaxThreadCount()更改最大的线程数。默认maxThreadCount()是
QThread::idealThreadCount()函数的结果。 - 使用
activeThreadCount()函数返回当前正在运行的线程数。注:该函数的返回值可能会大于最大线程数maxThreadCount
(3-4)预留线程【reserveThread】
调用reserveThread()函数预留一个线程。如果一个线程运行完成,则可以调用releaseThread()允许它被重用。注意:这个函数会增加活动线程的数量。
void QThreadPool::reserveThread()
(3-5)释放线程【releaseThrad】
releaseThread()函数的作用是:释放使用reserveThread()预留的线程。
注意:如果调用此函数时,没有预先预留线程,则会临时增加maxThreadCount()。当一个线程进入休眠状态,等待更多工作时,此时使用该函数很有用,因为它允许其他线程继续工作。在使用中,需确保在完成等待后再调用reserveThread(),以便线程池能够正确维护活动线程的数量。

本文详细介绍Qt中的QThreadPool线程池,涵盖其创建、使用方法,成员函数如设置自动删除、线程超时和线程数量控制等,并通过示例展示了如何继承QRunnable和在main函数中应用。
3万+

被折叠的 条评论
为什么被折叠?



