并发运行
QtConcurrent::run() 函数会在一个单独的线程中运行一个函数。该函数的返回值可通过QFuture API 获取。
QtConcurrent::run() 是一个重载方法。您可以将这些重载视为略有不同的模式。在基本模式下,传递给 QtConcurrent::run() 的函数只能向其调用者报告单一的计算结果。 在“带承诺”运行模式下,传递给 QtConcurrent::run() 的函数可以利用额外的QPromise API,该 API 支持多结果报告、进度报告、应调用方请求暂停计算,或应调用方要求停止计算。
该函数是Qt Concurrent 框架的一部分。
优化头文件
如果您包含<QtConcurrent> 头文件,整个Qt Concurrent 模块以及整个Qt Core 模块都会被包含进来,这可能会增加编译时间并增大二进制文件大小。要使用QtConcurrent::run()函数,您可以包含一个更具体的头文件:
#include <QtConcurrentRun>并发运行(基本模式)
传递给 QtConcurrent::run() 的函数可通过其返回值报告结果。
在单独的线程中运行函数
要在另一个线程中运行函数,请使用 QtConcurrent::run():
extern void aFunction();
QFuture<void> future = QtConcurrent::run(aFunction);这将使用默认的QThreadPool 获取的独立线程来运行aFunction 。您可以使用QFuture 和QFutureWatcher 类来监控该函数的状态。
若要使用专用线程池,可将QThreadPool 作为第一个参数传入:
extern void aFunction();
QThreadPool pool;
QFuture<void> future = QtConcurrent::run(&pool, aFunction);向函数传递参数
向函数传递参数的方法是在 QtConcurrent::run() 调用中,将参数紧跟在函数名之后。例如:
extern void aFunctionWithArguments(int arg1, double arg2, const QString &string);
int integer = ...;
double floatingPoint = ...;
QString string = ...;
QFuture<void> future = QtConcurrent::run(aFunctionWithArguments, integer, floatingPoint, string);在调用 QtConcurrent::run() 的位置会为每个参数创建一份副本,当线程开始执行该函数时,这些值会被传递给线程。在调用 QtConcurrent::run() 之后对参数所做的更改,线程将无法察觉。
请注意,QtConcurrent::run 不支持直接调用重载函数。例如,以下代码无法编译:
void foo(int arg);
void foo(int arg1, int arg2);
...
QFuture<void> future = QtConcurrent::run(foo, 42);最简单的解决方法是通过 lambda 表达式调用重载函数:
QFuture<void> future = QtConcurrent::run([] { foo(42); });或者,你可以通过使用static_cast 来告诉编译器选择哪个重载:
QFuture<void> future = QtConcurrent::run(static_cast<void(*)(int)>(foo), 42);或者使用qOverload :
QFuture<void> future = QtConcurrent::run(qOverload<int>(foo), 42);函数的返回值
函数的任何返回值均可通过 `QFuture` 获取:
extern QString functionReturningAString();
QFuture<QString> future = QtConcurrent::run(functionReturningAString);
...
QString result = future.result();如果不需要返回结果(例如,因为函数返回void ),使用接受函数对象的QThreadPool::start()重载版本会更高效。
如上所述,传递参数的方式如下:
extern QString someFunction(const QByteArray &input);
QByteArray bytearray = ...;
QFuture<QString> future = QtConcurrent::run(someFunction, bytearray);
...
QString result = future.result();请注意,QFuture::result() 函数会阻塞并等待结果可用。请使用QFutureWatcher 来获取函数执行完成且结果可用时的通知。
其他 API 功能
使用成员函数
QtConcurrent::run() 还接受成员函数的指针。在 Qt 6 中,第一个参数必须是成员函数的指针,随后可以是 const 引用或该类的实例指针。 传递 const 引用在调用 const 成员函数时非常有用;传递指针则适用于调用会修改实例的非 const 成员函数。
例如,要在另一个线程中调用 `QByteArray::split()`(一个 const 成员函数),可按以下方式操作:
// call 'QList<QByteArray> QByteArray::split(char sep) const' in a separate thread
QByteArray bytearray = "hello world";
QFuture<QList<QByteArray> > future = QtConcurrent::run(&QByteArray::split, bytearray, ' ');
...
QList<QByteArray> result = future.result();调用非const成员函数的实现方式如下:
// call 'void QImage::invertPixels(InvertMode mode)' in a separate thread
QImage image = ...;
QFuture<void> future = QtConcurrent::run(&QImage::invertPixels, &image, QImage::InvertRgba);
...
future.waitForFinished();
// At this point, the pixels in 'image' have been inverted使用lambda函数
调用 lambda 函数的方法如下:
QFuture<void> future = QtConcurrent::run([=]() {
// Code in this block will run in another thread
});
...若要调用一个会修改按引用传递的对象的函数,请按以下方式操作:
static void addOne(int &n) { ++n; }
...
int n = 42;
QtConcurrent::run(&addOne, std::ref(n)).waitForFinished(); // n == 43使用可调用对象的方法如下:
struct TestClass
{
void operator()(int s1) { s = s1; }
int s = 42;
};
...
TestClass o;
// Modify original object
QtConcurrent::run(std::ref(o), 15).waitForFinished(); // o.s == 15
// Modify a copy of the original object
QtConcurrent::run(o, 42).waitForFinished(); // o.s == 15
// Use a temporary object
QtConcurrent::run(TestClass(), 42).waitForFinished();
// Ill-formed
QtConcurrent::run(&o, 42).waitForFinished(); // compilation error使用 Promise 进行并发运行
与 QtConcurrent::run() 的基本模式相比,“带 Promise 运行”模式为正在运行的任务提供了更强的控制能力。它允许报告正在运行任务的进度、返回多个结果、在收到请求时暂停执行,或应调用方的要求取消任务。
必填参数 QPromise
在“带承诺运行”模式下传递给 QtConcurrent::run() 的函数,应包含一个额外参数,其类型为QPromise<T> & ,其中T 是计算结果的类型(该类型应与 QtConcurrent::run() 返回的QFuture<T> 的类型T 匹配),例如:
extern void aFunction(QPromise<void> &promise);
QFuture<void> future = QtConcurrent::run(aFunction);promise 参数会在 QtConcurrent::run() 函数内部进行实例化,其引用会被传递给被调用的aFunction ,因此用户无需自行实例化该参数,也无需在此模式下调用 QtConcurrent::run() 时显式传递它。
类型为QPromise 的额外参数必须始终作为函数参数列表中的第一个参数出现,例如:
extern void aFunction(QPromise<void> &promise, int arg1, const QString &arg2);
int integer = ...;
QString string = ...;
QFuture<void> future = QtConcurrent::run(aFunction, integer, string);报告结果
与 QtConcurrent::run() 的基本模式不同,在“带 Promise 运行”模式下传递给 QtConcurrent::run() 的函数应始终返回 void 类型。结果报告通过类型为QPromise 的附加参数完成。它还支持多结果报告,例如:
void helloWorldFunction(QPromise<QString> &promise)
{
promise.addResult("Hello");
promise.addResult("world");
}
QFuture<QString> future = QtConcurrent::run(helloWorldFunction);
...
QList<QString> results = future.results();注意:无需 调用QPromise::start() 和QPromise::finish() 来标记计算的开始和结束(就像通常在使用QPromise 时那样)。QtConcurrent::run() 会在执行开始前和结束后自动调用这些函数。
暂停和取消执行
QPromise API 还支持根据需求暂停和取消计算:
void aFunction(QPromise<int> &promise)
{
for (int i = 0; i < 100; ++i) {
promise.suspendIfRequested();
if (promise.isCanceled())
return;
// computes the next result, may be time consuming like 1 second
const int res = ... ;
promise.addResult(res);
}
}
QFuture<int> future = QtConcurrent::run(aFunction);
... // user pressed a pause button after 10 seconds
future.suspend();
... // user pressed a resume button after 10 seconds
future.resume();
... // user pressed a cancel button after 10 seconds
future.cancel();调用 `future.suspend() ` 会请求正在运行的任务暂停其执行。调用此方法后,正在运行的任务将在其迭代循环中下一次调用 `promise.suspendIfRequested() ` 时进入暂停状态。此时,该任务将在调用 `promise.suspendIfRequested()` 时被阻塞。该被阻塞的调用将在调用 `future.resume() ` 后解除阻塞。 请注意,suspendIfRequested() 内部使用等待条件来解除阻塞,因此运行中的线程会进入空闲状态,而不是在阻塞期间浪费资源,以便周期性地检查是否收到了来自调用者线程的恢复请求。
最后一行对future.cancel() 的调用会导致后续对promise.isCanceled() 的调用返回true ,而aFunction 将立即返回,不再报告任何进一步的结果。
注意: 取消后无需 调用QPromise::finish() 来停止计算(就像通常使用QPromise 时那样)。QtConcurrent::run() 在执行完成后会自动调用该方法。
进度报告
还可以独立于结果报告来报告任务的进度,例如:
voidaFunction(QPromise<int> &promise)
{
promise.setProgressRange(0, 100);
intresult= 0;
for(inti= 0; i< 100;++i) {
// 计算任务的一部分
const intpart=...;
result+=part;
promise.setProgressValue(i);
}
promise.addResult(result);
}
QFutureWatcher<int>监听器;
QObject::connect(&watcher, &QFutureWatcher::progressValueChanged, [](intprogress){
...;// 根据进度更新 GUI
qDebug() << "current progress:" << progress;
});
watcher.setFuture(QtConcurrent::run(aFunction));调用方为 QtConcurrent::run() 返回的 `QFuture ` 安装 `QFutureWatcher `,以便连接其 `progressValueChanged() ` 信号,并据此更新图形用户界面等内容。
使用重载的 operator()() 调用函数
默认情况下,在“Run With Promise”模式下,QtConcurrent::run() 不支持带有重载 operator()() 的函数对象。对于重载的函数对象,用户需要显式指定结果类型作为传递给 QtConcurrent::run() 的模板参数,例如:
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.