QThreadPool 类

QThreadPool 类管理一组 QThreads。更多信息...

头文件 #include <QThreadPool>
CMakefind_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmakeQT += core
继承自 QObject

注意: 此类中所有函数都是 线程安全的.

属性

公共函数

QThreadPool(QObject *parent = nullptr)
virtual~QThreadPool()
intactiveThreadCount() const
voidclear()
(since 6.0) boolcontains(const QThread *thread) const
intexpiryTimeout() const
intmaxThreadCount() const
voidreleaseThread()
voidreserveThread()
voidsetExpiryTimeout(int expiryTimeout)
voidsetMaxThreadCount(int maxThreadCount)
voidsetStackSize(uint stackSize)
voidsetThreadPriority(QThread::Priority priority)
uintstackSize() const
voidstart(QRunnable *runnable, int priority = 0)
voidstart(Callable &&callableToRun, int priority = 0)
(since 6.3) voidstartOnReservedThread(QRunnable *runnable)
(since 6.3) voidstartOnReservedThread(Callable &&callableToRun)
QThread::PrioritythreadPriority() const
booltryStart(QRunnable *runnable)
booltryStart(Callable &&callableToRun)
booltryTake(QRunnable *runnable)
boolwaitForDone(int msecs = -1)

静态公共成员

QThreadPool *globalInstance()

详细描述

QThreadPool 管理和回收单个 QThread 对象,以帮助减少使用线程的程序中的线程创建成本。每个 Qt 应用程序都有一个全局的 QThreadPool 对象,可以通过调用 globalInstance()() 来访问。

要使用 QThreadPool 的线程之一,需要继承 QRunnable 并实现 run() 虚函数。然后创建该类的对象,并将其传递给 QThreadPool::start()。

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()->start(hello);

默认情况下,QThreadPool 会自动删除 QRunnable。可以使用 QRunnable::setAutoDelete() 来更改自动删除标志。

QThreadPool 支持通过在 QRunnablerun() 函数内部调用 tryStart(this) 来多次执行相同的 QRunnable。如果启用 autoDelete,那么 QRunnable 将在最后一个线程退出 run 函数时被删除。当 autoDelete 启用时,多次使用相同的 QRunnable 调用 start() 将创建竞争条件,因此不建议这样做。

长时间未使用的线程将会过期。默认的超时时间为 30000 毫秒(30 秒)。这可以通过使用 setExpiryTimeout() 修改。设置负的过时时间会禁用过时机制。

调用 maxThreadCount() 来查询要使用的最大线程数。如果有需要,可以使用 setMaxThreadCount() 来更改限制。默认的 maxThreadCount() 是 QThread::idealThreadCount。函数 activeThreadCount() 返回当前正在工作的线程数。

reserveThread() 函数为外部使用保留线程。使用完毕后,请调用 releaseThread(),以便它可能被重用。本质上讲,这些函数临时增加或减少活动线程数,并在实现对 QThreadPool 不可见的耗时操作时非常有用。

注意,QThreadPool 是用于管理线程的低级类,请参阅 Qt 并发模块以了解高级替代方案。

另请参阅QRunnable

属性文档

[只读] activeThreadCount : const int

此属性表示线程池中活动的线程数。

注意:此函数可能会返回一个大于 maxThreadCount 的值。更多的细节请参阅 reserveThread()。

访问函数

intactiveThreadCount() const

另请参阅reserveThread() 和 releaseThread

expiryTimeout : int

此属性表示线程过期超时值(毫秒)。

expiryTimeout 毫秒内未被使用的线程被认为是过期的,并将退出。需要时将重新启动这些线程。默认的 expiryTimeout 是 30000 毫秒(30 秒)。如果 expiryTimeout 是负数,新创建的线程将不会过期,例如,它们将不会退出,直到线程池被销毁。

注意,设置 expiryTimeout 对已运行的线程没有影响。只有新创建的线程将使用新的 expiryTimeout。我们建议在创建线程池后立即设置 expiryTimeout,但在调用 start() 之前。

访问函数

intexpiryTimeout() const
voidsetExpiryTimeout(int expiryTimeout)

maxThreadCount : int

此属性保存线程池使用的最大线程数。当创建QThread::idealThreadCount() 时,此属性将默认为值。

注意:即使 maxThreadCount 限制为零或负数,线程池也将始终使用至少 1 个线程。

maxThreadCount 的默认值为 QThread::idealThreadCount()。

访问函数

intmaxThreadCount() const
voidsetMaxThreadCount(int maxThreadCount)

stackSize : uint

此属性保存线程池工作线程的堆栈大小。

当线程池创建新线程时才使用此属性的值。更改它对已创建或正在运行的线程没有影响。

默认值为 0,这将使 QThread 使用操作系统的默认堆栈大小。

访问函数

uintstackSize() const
voidsetStackSize(uint stackSize)

[since 6.2] threadPriority : QThread::Priority

此属性保存新工作线程的线程优先级。

当线程池启动新线程时使用此属性的值。更改它对已运行的线程没有影响。

默认值为 QThread::InheritPriority,这将使 QThread 使用与QThreadPool 对象相同的优先级。

此属性是在 Qt 6.2 中引入的。

访问函数

QThread::PrioritythreadPriority() const
voidsetThreadPriority(QThread::Priority priority)

参见 QThread::Priority

成员函数文档

QThreadPool::QThreadPool(QObject *parent = nullptr)

使用给定的 parent 构造线程池。

[virtual noexcept] QThreadPool::~QThreadPool()

销毁QThreadPool。该函数将阻塞直到所有可运行的任务都已完成。

void QThreadPool::clear()

从队列中删除尚未启动的可运行任务。对于返回 truerunnable->autoDelete() 的可运行任务进行删除。

参见 start

[since 6.0] bool QThreadPool::contains(const QThread *thread) const

如果 thread 是此线程池管理的线程,则返回 true

此函数是在 Qt 6.0 中引入的。

[静态] QThreadPool *QThreadPool::globalInstance()

返回全局 QThreadPool 实例。

void QThreadPool::releaseThread()

释放由 reserveThread() 调用之前预留的线程。

注意:未事先预留线程而调用此函数会临时增加 maxThreadCount。这在线程因等待更多工作而休眠时很有用,允许其他线程继续执行。务必在等待完成后调用 reserveThread(),以便线程池能正确维护 activeThreadCount

另请参阅:reserveThread

void QThreadPool::reserveThread()

预留一个线程,不考虑 activeThreadCountmaxThreadCount

完成对该线程的使用后,调用 releaseThread() 允许其被重用。

注意:即使预留 maxThreadCount 或更多线程,线程池仍将允许至少一个线程。

注意:此函数会增加报告的活动的线程数。这意味着通过使用此函数,activeThreadCount() 返回的值可能大于 maxThreadCount

另请参阅:releaseThread

void QThreadPool::start(QRunnable *runnable, int priority = 0)

预留一个线程并使用它来运行 runnable,除非这个线程会使当前线程数超过 maxThreadCount。在这种情况下,将 runnable 添加到运行队列中。可以使用 priority 参数来控制运行队列的执行顺序。

注意:如果 runnable->autoDelete() 返回 true,则线程池将拥有 runnable 的所有权,并在 runnable->run() 返回后自动删除 runnable。如果 runnable->autoDelete() 返回 false,则 runnable 的所有权保留在调用者处。注意,在此函数调用之后在 runnable 上更改自动删除设置会导致未定义的行为。

template <typename Callable, QRunnable::if_callable<Callable> = true> void QThreadPool::start(Callable &&callableToRun, int priority = 0)

这是重载函数。

预留一个线程并使用它来运行 callableToRun,除非这个线程会使当前线程数超过 maxThreadCount。在这种情况下,将 callableToRun 添加到运行队列中。可以使用 priority 参数来控制运行队列的执行顺序。

注意:只有当 Callable 是一个可以无参调用的函数或函数对象时,此函数才会参与到重载解析。

注意:在 Qt 版本 6.6 之前,此函数接受 std::function,因此不能处理移动只能调用者。

[since 6.3] void QThreadPool::startOnReservedThread(QRunnable *runnable)

使用 reserveThread() 释放之前保留的线程,并使用它来运行 runnable

注意:如果 runnable->autoDelete() 返回 true,则线程池将拥有 runnable 的所有权,并在 runnable->run() 返回后自动删除 runnable。如果 runnable->autoDelete() 返回 false,则 runnable 的所有权保留在调用者处。注意,在此函数调用之后在 runnable 上更改自动删除设置会导致未定义的行为。

注意:如果没有线程被保留,调用此函数会导致未定义行为。

此函数自 Qt 6.3 中引入。

另请参阅:reserveThread() 和 start()。

[自 6.3] 模板 <typename Callable, QRunnable::if_callable<Callable> = true> void QThreadPool::startOnReservedThread(Callable &&callableToRun)

这是重载函数。

使用 reserveThread() 释放之前保留的线程,并使用它来运行 callableToRun

注意:只有当 Callable 是一个可以无参调用的函数或函数对象时,此函数才会参与到重载解析。

注意:在 Qt 版本 6.6 之前,此函数接受 std::function,因此不能处理移动只能调用者。

此函数自 Qt 6.3 中引入。

bool QThreadPool::tryStart(QRunnable *runnable)

尝试为运行 runnable 保留线程。

如果在调用时没有线程可用,则此函数不执行任何操作并返回 false。否则,将立即使用一个可用的线程运行 runnable,并返回 true

注意:在成功的情况下,如果 runnable->autoDelete() 返回 true,线程池将获取 runnable 的所有权,并且在 runnable->run() 返回后,线程池将自动删除该Runnable。如果 runnable->autoDelete() 返回 false,则所有权保留在调用者处。请注意,在调用此函数后更改 runnable 的自动删除行为会导致未定义行为。