3. 使用QtConcurrent::run执行异步任务
任务目标
使用 QtConcurrent::run 将一个计算密集型函数提交到后台线程池执行,主线程保持响应;通过返回的 QFuture 对象获取异步任务的结果,并验证任务确实在非 GUI 线程中运行。
环境与依赖
- Qt 5.10+ 或 Qt 6(含 Concurrent 模块)
- 项目文件
.pro中添加:QT += concurrent - 编译器需支持 C++11 或更高版本
关键完整代码
// main.cpp
#include <QCoreApplication>
#include <QtConcurrent>
#include <QFuture>
#include <QThread>
#include <QDebug>
// 后台执行的耗时函数:计算从 1 到 n 的累加和
int sumUpTo(int n) {
qInfo() << "任务运行线程:" << QThread::currentThread();
int sum = 0;
for (int i = 1; i <= n; ++i) {
sum += i;
// 模拟耗时操作
QThread::msleep(2);
}
return sum;
}
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
qInfo() << "主线程:" << QThread::currentThread();
// 提交异步任务,返回 QFuture 用于获取结果
QFuture<int> future = QtConcurrent::run(sumUpTo, 100);
// 主线程不被阻塞,可继续执行其他操作
qInfo() << "任务已提交,主线程继续执行...";
// 等待任务完成并获取结果
future.waitForFinished();
int result = future.result();
qInfo() << "计算结果:" << result;
return 0;
}
运行与验证
- 创建 Qt 控制台项目,将上述代码保存为
main.cpp,在.pro文件中添加QT += concurrent。 - 编译并运行程序。
- 通过条件:程序输出中“任务运行线程”的线程地址与“主线程”的线程地址不同,且最终输出“计算结果: 5050”(1 到 100 的累加和)。
预期输出(示例)
主线程: QThread(0x...)
任务已提交,主线程继续执行...
任务运行线程: QThread(0x...)
计算结果: 5050
其中两行线程地址不同,即证明 sumUpTo 在后台线程池线程中执行,而非主线程。
关键说明
QtConcurrent::run默认使用全局线程池,无需手动创建QThread对象。future.waitForFinished()会阻塞当前线程直到任务完成;若不想阻塞,可改用QFutureWatcher的信号槽机制,但本案例为最小闭环,直接阻塞等待结果。- 若函数需要多个参数,直接在
run中依次传入即可,例如QtConcurrent::run(func, arg1, arg2)。