Qt中的多线程

Qt中的多线程


目录

1 为什么需要多线程
2 Qt中使用多线程的一些注意事项
3 QThread类
  3.1 QThread类的主要接口
  3.2 线程的优先级
4 通过继承QThread类实现多线程
5 从QObject类进行派生实现多线程
5 小结


1 为什么需要多线程

在现代化的程序设计开发中,多进程、多线程是经常采用的设计方式。在Qt程序中,默认线程(主线程)为窗口线程,当Qt程序在某些情况下需要处理复杂逻辑的时候(比如需要较长时间的网络操作、耗时的数据处理等)可能会占用很长的时间,这时候可能会导致窗口线程响应缓慢(UI响应卡顿),这时候通过多线程设计让多个逻辑事件分配在多个线程中进行操作,并处理好多个线程间的同步与交互,就能极大的提升程序的用户体验和程序执行效率。

2 使用多线程的一些注意事项

1、Qt中窗口所在的线程为默认主线程,窗口的事件处理和控件的数据更新在此线程进行。

    2、子线程和主线程之间的数据传递主要通过信号槽机制进行。
    3、子线程用于负责非UI部分的后台逻辑,不可操作窗口中的对象。


3 QThread类

QThread类是Qt提供的一个不依赖于平台的多线程类。

    在使用时,通常会定义一个继承QThread类的自定义类,重定义虚函数run()的实现;用一个从该自定义类实例化的对象来管理一个线程;在主线程中通过对象的start()接口来启动线程(start()接口底层会调用run()实现);在run()实现中调用exit()或者quit()能够结束线程的事件循环,在主线程中调用terminate()可以强制结束线程。
    但也可以通过从QObject类进行派生的方式来实现多线程,这种方式使用起来会更加灵活,但是在代码实现上会更复杂一些。

3.1 QThread类的主要接口

QThread类是继承自QObject类的,其中主要的一些接口如下:

        1、[公共函数] 判断线程是否结束:bool isFinished()
        2、[公共函数] 判断线程是否正在运行:bool isRunning()
        3、[公共函数] 获得线程的优先级:Priority priority()
        4、[公共函数] 设置线程的优先级:void setPriority(Priority priority)
        5、[公共函数] 退出事件循环:void exit(int returnCode = 0)
        6、[公共函数] 阻塞线程执行直到线程结束,或者time 毫秒:void wait(unsigned long time)
        7、[公共槽函数] 退出线程事件循环:void quit()
        8、[公共槽函数] 根据priority,开始调度、执行线程:void start(Priority priority)
        9、[公共槽函数] 终止线程:void terminate()
        10、[信号] 在线程快结束完成时发射:void finished()
        11、[信号] 在线程调用run()实现前发射:void started()
        12、[静态公共函数] 获得系统可运行的线程的数量:int idealThreadCount()
        13、[静态公共函数] 强制当前线程休眠msecs:int msleep(unsigned long msecs)
        14、[静态公共函数] 强制当前线程休眠secs:int sleep(unsigned long secs)
        15、[静态公共函数] 强制当前线程休眠usecs:int usleep(unsigned long usecs)
        16、[保护函数] 线程执行体虚函数:virtual void run()
        17、[保护函数] 进入线程事件循环:int exec()

3.2 线程的优先级

在QThread类中声明了从最低到最高的8个优先级(默认情况下为最高优先级QThread::InheritPriority),分别为:

        QThread::IdelPriority
        QThread::LowestPriority
        QThread::LowPriority
        QThread::NormalPriority
        QThread::HighPriority
        QThread::HigestPriority
        QThread::InheritPriority


4 通过继承QThread类实现多线程

通过自定义一个继承QThread类的自定义类,是在Qt开发中最常见的实现多线程的方式。

    这种方式的优势在于:
        1、可以直接重写run()函数,实现线程的执行逻辑。
        2、可以通过start()函数启动线程,比较直观和简单。
    但这种方式的劣势也很明显:
        1、在多线程中,直接操作QObject派生类的成员可能会导致线程安全问题,需要进行额外的同步处理。
        2、QThread类的创建和销毁需要小心处理,避免资源泄漏和线程未正常退出的情况。
    在具体的操作上,通常要经过如下步骤:
        1、定义一个继承QThread类的自定义类。

class MyThread : public QThread
{Q_OBJECT
public:explicit MyThread(QObject *parent = nullptr);
protected:void run() override;
};

        2、在自定义类中重写父类QThread的run()方法,在该实现中编写子线程的具体逻辑、处理、流程。

void MyThread::run()
{// 执行多线程的工作逻辑// ...
}

        3、在主线程中,创建一个子线程对象,将自定义的子线程类实例化,并连接适当的信号槽来处理工作完成的事件。

MyThread* thread = new MyThread(this);
connect(thread, &MyThread::finished, this, &MainWindow::handleThreadFinished);

        4、在主线程中,通过创建的子线程对象,调用start(),启动子线程。

thread->start();

        5、在主线程中和子线程,通过信号槽处理线程之间的数据传递、处理逻辑。
        6、在合适的时候,对线程的资源进行合理的释放


5 从QObject类进行派生实现多线程

通过从QObject类进行派生实现多线程,是在Qt开发中另一种使用较多的实现多线程的方式。

    这种方式的优势在于:
        1、QObject类提供了信号槽机制,方便多线程之间的通信和数据传递。
        2、可以利用Qt的事件循环机制处理事件,例如定时器事件、网络事件等。
        3、可以使用Qt提供的线程安全的容器和工具类,方便进行线程间的数据共享和同步。
    但这种方式的劣势在于:
        1、无法直接重写run()函数,需要使用QRunnable接口或QtConcurrent库来实现线程的执行逻辑。
        2、对象的生命周期和线程的生命周期紧密相关,需要小心处理对象的创建和销毁,避免线程结束后对象仍然存在。
    在具体的操作上,通常要经过如下步骤:
        1、创建一个QObject类的派生类,作为多线程的工作对象

class MyWorker : public QObject
{Q_OBJECT
public:explicit MyWorker(QObject *parent = nullptr);
public slots:void doWork();
signals:void workFinished();
};

        2、在创建的QObject类的派生类中,定义一个槽函数 doWork(),用于执行多线程的工作逻辑。

void MyWorker::doWork()
{// 执行多线程的工作逻辑// ...// 工作完成后发射信号emit workFinished();
}

        3、在主线程中,创建一个不指定父对象的QThread对象thread,并将QObject派生类的对象worker移动到这个线程对象thread中。

QThread* thread = new QThread;
MyWorker* worker = new MyWorker;
worker->moveToThread(thread);

        4、连接MyWorker对象的 workFinished() 信号到适当的槽函数,以处理工作完成的事件。

QObject::connect(worker, &MyWorker::workFinished, this, &MainWindow::handleWorkFinished);

启动线程并调用 doWork() 函数开始执行多线程工作。

thread->start();
QMetaObject::invokeMethod(worker, "doWork");

        5、通过以上步骤,我们就可以从QObject类派生实现多线程,并利用信号槽机制进行线程间的通信和数据传递了。

    注意,在这个例子中,我们将MyWorker对象移动到了新创建的线程中,并在主线程中通过信号槽机制连接工作完成的信号。这样,当 doWork() 函数执行完成后,会自动发射 workFinished() 信号,触发相应的槽函数执行。


6 小结

整体而言,从QObject类派生实现多线程会更加的灵活和功能强大,比较适合复杂的多线程应用场景;通过信号槽机制和事件循环,可以方便地实现线程间的通信和处理。而继承QThread类实现多线程相对简单,适用于简单的线程逻辑。在选择时,需要根据具体的需求和应用场景来决定使用哪种方式。

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

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

相关文章

【机器学习 西瓜书】期末复习笔记整理

一些杂点: 测试集如何归一化? —— 不是用测试集的均值和标准差,而是用训练集的! 机器学习: 对计算机一部分数据进行学习,然后对另外一些数据进行预测与判断。 参考计算例题: 机器学习【期末复习…

多汗症是否与情绪有关?

多汗症与情绪之间确实存在密切的关系。情绪波动、紧张、焦虑等心理因素是多汗症的常见诱因之一。多汗症患者在情绪激动或紧张时,常常会出现出汗量明显增加的情况。 首先,我们需要了解多汗症的基本病理生理机制。多汗症是由于交感神经过度兴奋引起汗腺过…

Spark-RDD的依赖

RDD的依赖 rdd之间是有依赖关系 窄依赖 每个父RDD的一个Partition最多被子RDD的一个Partition所使用父rdd和子rdd的分区是一对一 mapflatMapfliter 宽依赖 父RDD的Partition会被多个子RDD的Partition所使用父rdd和子rdd的分区是一对多 grouBy()grouByKey()sortBy()sortByKey()…

PyCharm安装使用教程2024

简介 PyCharm是一种PythonIDE(Integrated Development Environment,集成开发环境),带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单…

[oeasy]python0004_游乐场_和python一起玩耍_python解释器_数学运算

和python玩耍 🥊 Python 回忆 上次 了解shell环境中的命令 命令作用whoami显示当前用户名pwd显示当前文件夹ls列出当前文件夹下的内容python3仿佛进入大于号黑洞 这python3 怎么玩啊!😠 说好的python教程呢?🤔 运…

vue2使用Lottie

文章目录 学习链接1.安装依赖2.创建lottie组件3.在相对应的页面应用4.相关data.json5.测试效果 学习链接 原文链接&#xff1a;lottie在vue中的使用 lottie官网&#xff1a;https://lottiefiles.com/ 1.安装依赖 npm install lottie-web2.创建lottie组件 <template>…

5G+体育 贵阳电信为亚高原训练基地插上“数字羽翼”

2023年是《5G应用“扬帆”行动计划&#xff08;2021—2023年&#xff09;》的收官之年&#xff0c;5G融合应用正在从点状示范向规模化发展。截至2023年10月底&#xff0c;我国开通5G基站总数达321.5万个&#xff0c;已经建成了全球规模最大、技术领先的5G网络。目前&#xff0c…

MetaGPT前期准备与快速上手

大家好&#xff0c;MetaGPT 是基于大型语言模型&#xff08;LLMs&#xff09;的多智能体协作框架&#xff0c;GitHub star数量已经达到31.3k。 接下来我们聊一下快速上手 这里写目录标题 一、环境搭建1.python 环境2. MetaGpt 下载 二、MetaGPT配置1.调用 ChatGPT API 服务2.简…

Maven的安装和配置

国内Maven仓库之阿里云Aliyun仓库地址及设置 用过Maven的都知道Maven的方便便捷&#xff0c;但由于某些网络原因&#xff0c;访问国外的Maven仓库不便捷&#xff0c;好在阿里云搭建了国内的maven仓库。 需要使用的话&#xff0c;要在maven的settings.xml 文件里配置mirrors的子…

HTTP 常见协议:选择正确的协议,提升用户体验(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

opencv在linux上的编译

首先我们需要下载源码&#xff0c;我这里直接使用的是最新的4.x的版本&#xff0c;获取源码 wget -O opencv.zip https://github.com/opencv/opencv/archive/4.x.zip官方做法&#xff0c;链接如下&#xff1a;https://docs.opencv.org/4.x/d7/d9f/tutorial_linux_install.html&…

Java有哪些异常处理方式?

在Java中&#xff0c;异常处理主要通过try-catch语句块来实现。以下是Java中异常处理的几种主要方式&#xff1a; Try-Catch块&#xff1a;这是最常见的异常处理方式。在try块中编写可能会抛出异常的代码&#xff0c;然后在catch块中处理这些异常。可以有多个catch块来处理不同…

SQL语句详解二-DDL(数据定义语言)

文章目录 操作数据库创建&#xff1a;Create查询&#xff1a;Retrieve修改&#xff1a;Update删除&#xff1a;Delete使用数据库 操作表常见的几种数据类型创建&#xff1a;Create复制表 查询&#xff1a;Retrieve修改&#xff1a;Update删除&#xff1a;Delete 操作数据库 创…

Stable Diffusion XL Turbo 文生图和图生图实践

本篇文章聊聊&#xff0c;如何快速上手 Stable Diffusion XL Turbo 模型的文生图和图生图实战。 写在前面 分享一篇去年 11 月测试过模型&#xff0c;为月末分享的文章做一些技术铺垫&#xff0c;以及使用新的环境进行完整复现。 本篇文章相关的代码保存在 soulteary/docker…

【教学类-43-18】A4最终版 20240111 数独11.0 十宫格X*Y=Z套(n=10),套用没有分割行列的A4横版模板

作品展示&#xff1a; 撑满格子的10宫格数独50%难度 50空 背景需求&#xff1a; 大4班有3位男孩做9宫格数独&#xff08;81格子&#xff0c;30%难度 24空&#xff09;非常娴熟&#xff0c;我观察他们基本都在10分钟内完成&#xff0c;其中一位男孩把九宫格题目给我看时表达自…

使用 EmbeddingBag 和 Embedding 完成词嵌入

&#x1f368; 本文为[&#x1f517;365天深度学习训练营学习记录博客\n&#x1f366; 参考文章&#xff1a;365天深度学习训练营\n&#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制]\n&#x1f680; 文章来源&#xff1a;[K同学的学习圈子](https://www.yuque.co…

iOS 位移枚举NS_OPTIONS(如何实现多个枚举值的同时传入判断)

一、场景 当我们使用枚举这个东西时&#xff0c;有时需要多个枚举值任一一个满足时就ture&#xff0c;但是常用的枚举NS_ENUM定义好的枚举只能挨个判断&#xff0c;写一坨就既不美观也不好阅读&#xff0c;如下&#xff1a; typedef NS_ENUM (NSInteger, RPTestType){RPTestT…

移除两个双向链表中的重复元素,每个链表中的元素不重复

移除两个双向链表中的重复元素&#xff0c;每个链表中的元素不重复&#xff0c;请给出算法。 ans: 该问题比单向链表要更加复杂一些&#xff0c;必须考虑并更新前向节点的指向情况&#xff0c;具体编码中存在一些难度&#xff0c;加上链表调试相对不容易&#xff0c;因此难度系…

技术专栏——你所不知道的 RocketMQ 的集群管理:副本机制

这些精彩的技术类型的体系化文章&#xff0c;后面我会放到公众号上&#xff0c;并集中在合集“分布式消息中间件专栏”中&#xff0c;欢迎大家去订阅我的公众号和视频号“架构随笔录”&#xff0c;大家可以订阅合集&#xff0c;这样更加方便喔&#xff0c;后面会出电子版本&…

C++采集亚马逊amazon产品数据教程

最近亚马逊电商非常火爆&#xff0c;今天我将用C语言写一个亚马逊商品数据的爬虫程序&#xff0c;只要是用来收集一些产品相关信息。例如产品自身特性以及产品所对应的销量&#xff0c;为了后期布局亚马逊做一些参考&#xff0c;提供数据支持&#xff0c;同时另外我也会用C语言…