百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

Qt Concurrent的使用_qt是什么意思

liebian365 2025-02-18 12:18 6 浏览 0 评论

1. 简介

QtConcurrent 命名空间提供了高级 api,使得无需使用诸如互斥、读写锁、等待条件或信号量等低级线程原语就可以编写多线程程序。使用 QtConcurrent 编写的程序会根据可用的线程处理器核心数量自动调整使用的线程数,这意味着编写的应用程序在部署到多核系统时将自动扩展。

当你发现你自己的程序UI运行不流畅时可以尝试将执行计算的函数放到QtConcurrent::run()中处理,这比改用QThread方便得多。

对于不同的需求可以参照下表:

生命周期

开发任务

解决方案

一次调用

在另一个线程中运行一个函数,函数完成时退出线程

1.编写函数,使用QtConcurrent::run 运行它

2.派生QRunnable,使用
QThreadPool::globalInstance()->start()运行它



3.派生QThread,重新实现QThread::run() ,使用QThread::start()运行它



一次调用

需要操作一个容器中所有的项。使用处理器所有可用的核心。一个常见的例子是从图像列表生成缩略图。

QtConcurrent 提供了map()函你数来将操作应用到容器中的每一个元素,提供了fitler()函数来选择容器元素,以及指定reduce函数作为选项来组合剩余元素。

一次调用

一个耗时运行的操作需要放入另一个线程。在处理过程中,状态信息需要发送会GUI线程。

使用QThread,重新实现run函数并根据需要发送信号。使用信号槽的queued连接方式将信号连接到GUI线程的槽函数。

持久运行

生存在另一个线程中的对象,根据要求需要执行不同的任务。这意味着工作线程需要双向的通讯。

派生一个QObject对象并实现需要的信号和槽,将对象移动到一个运行有事件循环的线程中并通过queued方式连接的信号槽进行通讯。

持久运行

生存在另一个线程中的对象,执行诸如轮询端口等重复的任务并与GUI线程通讯。

同上,但是在工作线程中使用一个定时器来轮询。尽管如此,处理轮询的最好的解决方案是彻底避免它。有时QSocketNotifer是一个替代。

多线程的一些替代技术:

替代技术

注解

QEventLoop::processEvents()

在一个耗时的计算操作中反复调用QEventLoop::processEvents() 可以防止界面的假死。尽管如此,这个方案可伸缩性并不太好,因为该函数可能会被调用地过于频繁或者不够频繁。

QTimer

后台处理操作有时可以方便地使用Timer安排在一个在未来的某一时刻执行的槽中来完成。在没有其他事件需要处理时,时间隔为0的定时器超时事件被相应

QSocketNotifier


QNetworkAccessManager


QIODevice::readyRead()

这是一个替代技术,替代有一个或多个线程在慢速网络执行阻塞读的情况。只要响应部分的计算可以快速执行,这种设计比在线程中实现的同步等待更好。与线程相比这种设计更不容易出错且更节能(energy efficient)。在许多情况下也有性能优势。

2. 准备工作

2.1 修改.pro文件

使用 QtConcurrent 模块,需要在 .pro 中添加: QT += concurrent

2.2 包含头文件和声明命名空间

#include 

using namespace QtConcurrent;

3. 运行

3.1 运行外部函数

要在另一个线程中运行一个函数,可以使用 QtConcurrent: : run () :

extern void aFunction();
QFuture future = QtConcurrent::run(aFunction);

3.2 运行成员函数

Run ()也接受指向成员函数的指针。第一个参数必须是常量引用或指向类实例的指针。在调用 const 成员函数时,通常使用 const 引用传递; 通常使用指针传递对于调用修改实例的非 const 成员函数。

例如,在一个单独的线程中调用 QByteArray: : split ()(一个 const 成员函数)是这样做的:

// call 'QList  QByteArray::split(char sep) const' in a separate thread
QByteArray bytearray = "hello world";
QFuture > future = QtConcurrent::run(bytearray, &QByteArray::split, ',');
...
QList result = future.result();

调用一个非常量成员函数是这样做的:

// call 'void QImage::invertPixels(InvertMode mode)' in a separate thread
QImage image = ...;
QFuture future = QtConcurrent::run(&image, &QImage::invertPixels, QImage::InvertRgba);
...
future.waitForFinished();
// At this point, the pixels in 'image' have been inverted

【粉丝福利】Qt开发学习资料包、大厂面试题、项目视频、学习路线,包括(Qt C++基础,数据库编程,Qt项目实战、Qt框架、QML、Opencv、qt线程等等)有需要的可以进企鹅裙937552610领取哦~

4. 向函数传递参数的方式

通过将参数添加到紧跟在函数名之后的 QtConcurrent::run()调用中来完成向函数传递参数。例如:

extern void aFunctionWithArguments(int arg1, double arg2, const QString &string);

int integer = ...;
double floatingPoint = ...;
QString string = ...;

QFuture future = QtConcurrent::run(aFunctionWithArguments, integer, floatingPoint, string);

运行的机制是:在调用 QtConcurrent: : run ()的地方复制每个参数,并在线程开始执行函数时将这些值传递给线程。调用 QtConcurrent: : run ()后对参数所做的更改对线程不可见。

5. 获取函数返回值的方式

返回值可以通过 QFuture 获得:

extern QString functionReturningAString();
QFuture future = QtConcurrent::run(functionReturningAString);
...
QString result = future.result();

注意,QFuture: : result ()函数阻塞并等待结果可用。当函数完成执行并且结果可用时,使用 QFutureWatcher 获得通知。

相关推荐

C#夯实基础-Lambda在List中的使用

在C#中基本类型比如List,Dictionary,数组等都有委托来实现相关的操作。此时Lambda表达式就可以使用了.实例1,查找字符串List的包含a的元素...

在C#中,如何实现对集合中元素的自定义排序?

在C#中,可以通过多种方式实现对集合中元素的自定义排序,主要包括:...

C++11 新特性面试题_c++ 11 面试题

1、C++11中引入了哪些新的智能指针类型?请描述它们的用法和区别。C++11中引入了三种新的智能指针类型:std::unique_ptr,std::shared_ptr,和std::weak_...

为什么要使用lambda表达式?原来如此,涨知识了

为什么要使用Lambda表达式先看几段Java8以前经常会遇到的代码:创建线程并启动...

[编程基础] Python lambda函数总结

Pythonlambda函数教程展示了如何在Python中创建匿名函数。Python中的匿名函数是使用lambda关键字创建的。...

硬核!Java 程序员必须掌握的 10 个 简化代码的 Lambda 表达式!

大家好,我是一位在架构师道路上狂奔的码农,今天给大家介绍一下程序员必须掌握的10个Lambda表达式,这些表达式几乎涵盖了在实际编程中经常用到的常见场景。相信通过这10个Lambda表...

一文读懂lambda表达式_lambda表达式由来

作者:youngyan,腾讯PCG数据工程工程师...

Java基础知识 - lambda 表达式_javalambda表达式用法

1、表达式语法1)lambda的命名采用的是数学符号λ;...

Python学习笔记 | 匿名函数lambda、映射函数map和过滤函数filter

什么是匿名函数?定义:没有函数名的自定义函数场景:函数体非常简单,使用次数很少,没有必要声明函数,通常搭配高阶函数使用。...

Java Lambda表达式详解(非常全面)

JavaLambda表达式是JDK8引入的,是一个比较重要的特性。@mikechenLambda表达式简介...

Python函数—lambda表达式_python中lambda函数的用法讲解

目录...

了解 Lambda:Python 中的单个表达式函数

Python中的lambda关键字提供了声明小型匿名函数的快捷方式。Lambda函数的行为与使用...

在C#中使用Lambda编写一个排序算法,比较其与传统排序算法的优劣

使用Lambda表达式编写排序算法在C#中,Lambda表达式可以用来简化排序逻辑的编写,尤其是在需要自定义排序规则时非常方便。以下示例展示了如何用Lambda表达式实现排序,并与传统排...

一日一技:python中的匿名函数 lambda用法

匿名函数lambda,语法如下:lambdaarguments:expression...

《回炉重造》——Lambda表达式_回炉重造是贬义词吗

前言Lambda表达式(LambdaExpression),相信大家对Lambda肯定是很熟悉的,毕竟我们数学上经常用到它,即λ。不过,感觉数学中的Lambda和编程语言中的Lamb...

取消回复欢迎 发表评论: