当前位置: 首页 > news >正文

QtConcurrent入门

QtConcurrent 是 Qt 提供的一个高级并发编程框架,它简化了并行算法的实现,让开发者能够更容易地利用多核处理器的优势。

1. QtConcurrent 基础

基本概念

QtConcurrent 提供了几种并行编程模式:

  • 并行映射:对容器中的每个元素应用函数

  • 并行过滤:基于条件筛选容器元素

  • 并行归约:将容器元素合并为单个结果

  • 并行运行:简单地在后台运行函数

准备工作

使用 QtConcurrent 前需要:

#include <QtConcurrent>

并在项目文件(.pro)中添加:

QT += concurrent

2. 基本用法

并行运行函数 (run)

最简单的用法是在另一个线程中运行函数:

// 定义一个普通函数
int computeSomething(int x) {return x * x;
}// 在后台线程中运行
QFuture<int> future = QtConcurrent::run(computeSomething, 10);// 获取结果(会阻塞直到结果可用)
int result = future.result();

也可以使用 lambda 表达式:

QFuture<int> future = QtConcurrent::run([](int x) {return x * x;
}, 10);

并行映射 (map)

对容器中的每个元素应用函数:

QList<int> list = {1, 2, 3, 4, 5};// 原地修改每个元素
QtConcurrent::map(list, [](int &x) {x *= 2;
});// list 现在是 {2, 4, 6, 8, 10}

并行映射并返回新容器 (mapped)

QList<int> list = {1, 2, 3, 4, 5};QFuture<QList<int>> future = QtConcurrent::mapped(list, [](int x) {return x * 2;
});QList<int> result = future.result();
// result 是 {2, 4, 6, 8, 10}

并行过滤 (filter)

QList<int> list = {1, 2, 3, 4, 5};// 原地过滤
QtConcurrent::filter(list, [](int x) {return x % 2 == 0; // 只保留偶数
});// list 现在是 {2, 4}

并行过滤并返回新容器 (filtered)

QList<int> list = {1, 2, 3, 4, 5};QFuture<QList<int>> future = QtConcurrent::filtered(list, [](int x) {return x % 2 == 0;
});QList<int> result = future.result();
// result 是 {2, 4}

并行归约 (reduce)

将容器元素合并为单个结果:

QList<int> list = {1, 2, 3, 4, 5};int sum = QtConcurrent::blockingReduced(list, [](int &result, int x) {result += x;
});// sum = 15

3. 监控异步操作

使用 QFutureWatcher 监控异步操作进度和结果:

QFutureWatcher<int> *watcher = new QFutureWatcher<int>();// 连接信号
connect(watcher, &QFutureWatcher<int>::finished, []() {qDebug() << "计算完成";
});connect(watcher, &QFutureWatcher<int>::progressValueChanged, [](int progress) {qDebug() << "进度:" << progress;
});// 启动异步计算
QFuture<int> future = QtConcurrent::run([]() {int result = 0;for (int i = 0; i < 100; ++i) {QThread::msleep(50); // 模拟耗时操作result += i;}return result;
});watcher->setFuture(future);

4. 高级特性

取消操作

QFuture<void> future = QtConcurrent::run([]() {while (!QThread::currentThread()->isInterruptionRequested()) {// 执行工作}
});// 取消操作
future.cancel();

设置线程池

QThreadPool::globalInstance()->setMaxThreadCount(4); // 设置最大线程数QtConcurrent::run(QThreadPool::globalInstance(), []() {// 使用全局线程池
});

链式操作

QList<int> list = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};QFuture<int> future = QtConcurrent::mapped(list, [](int x) {return x * x; // 平方}).filtered([](int x) {return x % 2 == 0; // 只保留偶数}).reduced([](int &result, int x) {result += x; // 求和});int result = future.result();

5. 注意事项

  1. 线程安全:确保被调用的函数是线程安全的

  2. GUI操作:不能在非主线程中直接操作GUI组件

  3. 异常处理:QtConcurrent 中抛出的异常需要通过 QFuture 捕获

  4. 性能考虑:对于非常小的任务,线程创建的开销可能超过并行化的收益

6. 简单示例

下面是一个完整的示例,演示如何使用 QtConcurrent 处理图像:

#include <QCoreApplication>
#include <QtConcurrent>
#include <QDebug>
#include <QImage>// 图像处理函数
QImage processImage(const QImage &image) {QImage result = image;for (int y = 0; y < result.height(); ++y) {for (int x = 0; x < result.width(); ++x) {QColor color = result.pixelColor(x, y);color.setRed(255 - color.red());   // 反色color.setGreen(255 - color.green());color.setBlue(255 - color.blue());result.setPixelColor(x, y, color);}}return result;
}int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 加载图像列表QList<QImage> images = {QImage("image1.png"), QImage("image2.png")};// 并行处理图像QFuture<QImage> future = QtConcurrent::mapped(images, processImage);// 监控进度QFutureWatcher<QImage> watcher;watcher.setFuture(future);QObject::connect(&watcher, &QFutureWatcher<QImage>::progressValueChanged,[](int progress) {qDebug() << "处理进度:" << progress;});QObject::connect(&watcher, &QFutureWatcher<QImage>::finished, [&]() {qDebug() << "所有图像处理完成";a.quit();});return a.exec();
}
http://www.lryc.cn/news/581530.html

相关文章:

  • #渗透测试#批量漏洞挖掘#HSC Mailinspector 任意文件读取漏洞(CVE-2024-34470)
  • 2025.7.6总结
  • 智能网盘检测软件,一键识别失效链接
  • ipmitool 使用简介(ipmitool sel list ipmitool sensor list)
  • 【JS逆向基础】数据分析之正则表达式
  • 支持向量机(SVM)在肝脏CT/MRI图像分类(肝癌检测)中的应用及实现
  • 【网络安全基础】第八章---电子邮件安全
  • QueryWrapper 类的作用与示例详解
  • GASVM+PSOSVM+CNN+PSOBPNN+BPNN轴承故障诊断
  • 微信小程序71~80
  • 玄机——第二章日志分析-redis应急响应
  • Python助力地热资源评估,掘金绿色能源新蓝海!
  • GIT: 一个用于视觉与语言的生成式图像到文本转换 Transformer
  • golang的defer
  • JAX study notes[15]
  • 百度文心大模型 4.5 开源深度测评:技术架构、部署实战与生态协同全解析
  • 前端环境nvm/pnpm下载配置
  • 在C#中,可以不实例化一个类而直接调用其静态字段
  • 【Elasticsearch入门到落地】15、DSL排序、分页及高亮
  • 【HarmonyOS】鸿蒙应用开发Text控件常见错误
  • 深入解析Vue中v-model的双向绑定实现原理
  • D3 面试题100道之(61-80)
  • Qt实现外网双向音视频通话/支持嵌入式板子/实时性好延迟低/可以加水印
  • C++基础复习笔记
  • 【网络系列】HTTP 429 状态码
  • Debezium日常分享系列之:认识Debezium Operator
  • Go语言实现双Token登录的思路与实现
  • UNIX程序设计基本概念和术语
  • 玄机——第一章日志分析-mysql应急响应
  • docker 无法拉取镜像解决方法