qt多线程使用方式

有5个方式:可以参考这个博客:Qt 中开启线程的五种方式_qt 线程_lucky-billy的博客-CSDN博客

注:为了实现更加灵活的线程管理(因为这5种都有一些不方便之处:QThread需要子类化且不能传参,moveToThread不能传参且只能移入一个对象而不是一个函数,QThreadPool 需要子类化QRunnable且只能启动一个对象,QtConcurrent支持传参但是不能管理它,std::thread能够传入函数以及给定实参但是不是qt方式了),我自己实现了一个更好用的线程管理类(支持指定一个函数,同时指定传入的实参,而且能管理该线程例如随时终止等),看我这个博客: qt自己实现方便的线程管理类_我是标同学的博客-CSDN博客

接下来,讲解这5种方式情况: 

1. 继承 QThread 重写 run 函数

class Thread : public QThread
{
    Q_OBJECT
public:
    virtual void run() override;
}
优点:构造使用方式简单,所有操作都放在run()方法里面。而且可以随时停止,因为这是以线程对象形式存在,我们可以对其进行各种管理。
缺点:不够灵活,只能运行run()里面的程序。此外,传入的函数不能同时给参数,只能另外一个函数设置其成员变量,run函数里读取该成员变量。

2. 继承 QObject 调用 moveToThread

QThread th;
Test test;
test.moveToThread(&th);
优点:使用简单,可以使用信号槽通信,很灵活。
缺点:每次都要创建线程,带来不必要资源开支。而且是整个对象给弄进去,也挺重的。

3. 继承 QRunnable 重新 run 函数,结合 QThreadPool 实现线程池

我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。

还有一个问题需要注意一下,QThread 是集成自 QObject 的,我们通常会使用信号槽与外界进行通信。而 QRunnable 并不是继承自 QObject 类的,所以他无法使用信号槽机制进行通信。这里推荐两种方法,一个是使用 QMetaObject::invokeMethod()函数。另一个是使用多重继承的方法,自定义类需要同时继承自 QRunnable 和 QObject

每个Qt应用程序都有一个全局 QThreadPool 对象,可以通过调用 globalInstance() 来访问它。==也可以单独创建一个 QThreadPool 对象使用。

class BPrint : public QRunnable
{
    void run()
    {
        for ( int count = 0; count < 5; ++count )
        {
            qDebug() << QThread::currentThread();
            QThread::msleep(1000);
        }
    }
};

一般情况下,我们不需要在 Qt 程序中创建线程池对象,**直接使用 Qt 为每个应用程序提供的线程池全局对象即可。得到线程池对象之后,调用 start() 方法**就可以将一个任务添加到线程池中,这个任务就可以被线程池内部的线程池处理掉了,使用线程池比自己创建线程的这种多种多线程方式更加简单和易于维护。
 

4. 使用 C++ 11 中的 std::thread

#include <thread>
void threadfun1()
{
    std::cout << "threadfun1 - 1\r\n" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "threadfun1 - 2" << std::endl;
}

void threadfun2(int iParam, std::string sParam)
{
    std::cout << "threadfun2 - 1" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "threadfun2 - 2" << std::endl;
}

int main()
{
    std::thread t1(threadfun1);
    std::thread t2(threadfun2, 10, "abc");
    t1.join();        // 等待线程 t1 执行完毕
    std::cout << "join" << std::endl;
    t2.detach();    // 将线程 t2 与主线程分离
    std::cout << "detach" << std::endl;
}
t1.join() 会等待t1线程退出后才继续往下执行t2.detach() 并不会等待,detach字符输出后,主函数退出,threadfun2还未执行完成,但是在主线程退出后,t2的线程也被已经被强退出

5. Qt QtConcurrent 之 Run 函数

简单来说,QtConcurrent::run() 函数会在一个单独的线程中执行,并且该线程取自全局 QThreadPool,该函数的返回值通过 QFuture API 提供。

// 需要传递的参数,则跟在函数名之后,依次加入 QFuture<void> future = QtConcurrent::run(FuncWithArguments, integer, string);

...

QString result = future.result();

需要注意的是:
1)该函数可能不会立即运行; 函数只有在线程可用时才会运行
2)通过 QtConcurrent::run() 返回的 QFuture 不支持取消、暂停,返回的 QFuture 只能用于查询函数的运行/完成状态和返回值
3) Qt Concurrent 已经从 QtCore 中移除并成为了一个独立的模块,所以想要使用 QtConcurrent 需要在 pro 文件中导入模块:
QT += concurrent
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/34977.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【leetcode】459. 重复的子字符串(easy)

给定一个非空的字符串 s &#xff0c;检查是否可以通过由它的一个子串重复多次构成。 示例 1: 输入: s “abab” 输出: true 解释: 可由子串 “ab” 重复两次构成。 示例 2: 输入: s “aba” 输出: false 示例 3: 输入: s “abcabcabcabc” 输出: true 解释: 可由子串 “ab…

ChatGPT等人工智能编写文章的内容今后将成为常态

BuzzFeed股价上涨200%可能标志着“转向人工智能”媒体趋势的开始。 周四&#xff0c;一份内部备忘录被华尔街日报透露BuzzFeed正计划使用ChatGPT聊天机器人-风格文本合成技术来自OpenAI&#xff0c;用于创建个性化盘问和将来可能的其他内容。消息传出后&#xff0c;BuzzFeed的…

ubuntu 20.04 RK3568网络的优先级设置

1、背景 硬件使用RK3568 CPU&#xff0c;操作系统采用ubuntu 20.04 Lxqt桌面的版本。硬件上具有一个有线以太网卡&#xff0c;一个wifi网卡&#xff0c;一个5G网卡。由于操作系统默认的网络优先级为有线网卡的最高&#xff0c;5G网卡次之。在一个业务应用中需要5G网卡的连接外…

文本三剑客之grep命令和awk命令 1.0 版本

grep awk 1.grep命令1.1 基本格式1.2 常用选项 2.awk命令2.1 awk工作原理2.2 awk命令格式2.3 awk常用内置变量 1.grep命令 1.1 基本格式 grep [选项]… 查找条件 目标文件1.2 常用选项 选项功能 -m [ x ]匹配x次 后停止,x为具体数字-v取反 -i忽略字符大小写 -n显示匹配的 …

Dynamic CRM开发 - 实体介绍

实体简介 在CRM中,实体(Entity)是数据的基本载体,也是构建业务逻辑网络的基础节点。 实体可以理解为数据库中的一张表(实体中的字段对应数据库表的字段),比如创建一个实体存储客户信息,创建一个实体存储产品信息,产品实体里可以创建一个查找类型的字段(类似表的外键)…

【Express.js】集成RabbitMQ

集成RabbitMQ 本节我们介绍在 express.js 中集成 rabbitmq. RabbitMQ 是一个消息队列中间件&#xff0c;常用于请求削峰&#xff0c;事务的队列处理&#xff0c;事件订阅机制的实现等。 准备工作 创建一个 express.js 项目&#xff08;本文基于evp-express-cli&#xff09;…

【三维编辑】Seal-3D:基于NeRF的交互式像素级编辑

文章目录 摘要一、引言二、方法2.1.基于nerf的编辑问题概述2.2.编辑指导生成2.3.即时预览的两阶段学生训练 三、实验四、代码总结 项目主页: https://windingwind.github.io/seal-3d/ 代码&#xff1a;https://github.com/windingwind/seal-3d/ 论文: https://arxiv.org/pdf/23…

创建一个Spring Boot项目

安装所需软件&#xff1a;首先确保你的计算机上已经安装了Java JDK和Maven构建工具。你可以从官方网站下载并按照说明进行安装。 创建一个新的Spring Boot项目&#xff1a;在命令行或终端中使用Maven命令创建一个新的Spring Boot项目。执行以下命令&#xff1a;mvn archetype:…

阿里云轻量应用服务器_2核4G4M_2核2G3M_性能测评

阿里云轻量应用服务器2核2G3M带宽108元一年&#xff0c;系统盘为50GB高效云盘&#xff1b;轻量服务器2核4G4M带宽&#xff0c;60GB高效云盘297.98元12个月。目前轻量应用服务器只有2核2G和2核4G有活动&#xff0c;阿里云百科分享阿里云轻量应用服务器入口&#xff1a; 目录 阿…

【Qt高阶】老Qt都不一定清楚的“QObject线程亲和性”【2023.08.13】

老Qt都不一定清楚的“线程亲和性” 与题目无关 感觉自己还挺2&#xff0c;有粉丝点了那个契约者会给up发个鼓励的话&#xff0c;我还以为是人私信发的&#xff0c;都挨个感谢了&#xff0c;后来才意识到是系统自动发的&#x1f623;&#x1f623;&#x1f623;。 自上上期视频对…

Three.js阴影

目录 Three.js入门 Three.js光源 Three.js阴影 Three.js纹理贴图 使用灯光后&#xff0c;场景中就会产生阴影。物体的背面确实在黑暗中&#xff0c;这称为核心阴影&#xff08;core shadow&#xff09;。我们缺少的是落下的阴影&#xff08;drop shadow&#xff09;&#…

【数据结构】——栈、队列的相关习题

目录 题型一&#xff08;栈与队列的基本概念&#xff09;题型二&#xff08;栈与队列的综合&#xff09;题型三&#xff08;循环队列的判空与判满&#xff09;题型四&#xff08;循环链表表示队列&#xff09;题型五&#xff08;循环队列的存储&#xff09;题型六&#xff08;循…

一文揭秘饿了么跨端技术的演进、实践与落地

跨端技术背景与演进历程 跨端&#xff0c;究竟跨的是哪些端&#xff1f; 自 90 年的万维网出现&#xff0c;而后的三十多年&#xff0c;我们依次经历了 PC 时代、移动时代&#xff0c;以及现在的万物互联&#xff08;的 IoT &#xff09;时代&#xff0c;繁荣的背后&#xff…

【Apollo】Apollo-ros版本架构学习与源码分析

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Apollo-ros版本架构学习与源码分析。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&a…

微信小程序如何自定义分享卡片文案和图片

微信小程序提供了onShareAppMessage方法&#xff0c;专门用来监听用户点击页面内转发按钮&#xff08;button 组件 open-type"share"&#xff09;或右上角菜单“转发”按钮的行为&#xff0c;并自定义转发内容。 > 注意&#xff1a;只有定义了此事件处理函数&…

Android studio 设置安卓手机

参考这个链接 ghttps://developer.android.com/studio/debug/dev-options 列出常用手机的设置&#xff0c;但是我的手机不在此列 Google Pixel Settings > About phone > Build number Samsung Galaxy S8 and later Settings > About phone > Software informa…

git: ‘lfs‘ is not a git command. see ‘git --help‘

在克隆hugging face里面的项目文件的时候&#xff0c;需要用到git lfs&#xff0c;本文介绍安装git lfs方法 在Ubuntu下 curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash sudo apt-get install git-lfs在Windows下 到这个链…

解决GitHub的速度很慢的几种方式

1. GitHub 镜像访问 这里提供两个最常用的镜像地址&#xff1a; https://hub.njuu.cf/search https://www.gitclone.com/gogs/search/clonesearch 也就是说上面的镜像就是一个克隆版的 GitHub&#xff0c;你可以访问上面的镜像网站&#xff0c;网站的内容跟 GitHub 是完整同步…

期权定价模型系列【4】—期权组合的Delta-Gamma-Vega中性

期权组合的Delta-Gamma-Vega中性 期权组合构建时往往会进行delta中性对冲&#xff0c;在进行中性对冲后&#xff0c;期权组合的delta敞口为0&#xff0c;此时期权组合仍然存在gamma与vega敞口。因此研究期权组合的delta-gamma-vega敞口中性是有必要的。 本文旨在对delta-gamma-…

关于新手学习STM32开发应该如何入门?

对于新手来说&#xff0c;学习STM32开发可能会感到困惑&#xff0c;尤其是在拿到开发板后该如何入门。在这里有嵌入式学习路线&#xff0c;毕设&#xff0c;各种项目&#xff0c;需要留个6。以下是部分内容概述&#xff1a;硬件介绍&#xff1a;了解STM32开发板的基本硬件组成和…