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

【QT学习十一】QThread

一、引言

        在现代软件开发中,多线程编程变得越来越重要,尤其是对于需要处理并发任务的应用程序。Qt C++ 框架提供了强大的多线程支持,使得开发者能够轻松地创建和管理多线程应用。

        在 Qt 中,多线程的实现主要基于 QThread 类。QThread 提供了一个线程对象,允许开发者通过继承 QThread 类并实现 run() 函数来定义线程的执行体

二、一个QThread实例

#include <QCoreApplication>
#include <QThread>
#include <QDebug>class MyThread : public QThread {
public:void run() override {for (int i = 0; i < 5; ++i) {qDebug() << "Thread is running" << i;sleep(1);}}
};int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 创建线程对象MyThread thread;// 启动线程thread.start();// 主线程继续执行其他任务for (int i = 0; i < 3; ++i) {qDebug() << "Main thread is running" << i;QThread::sleep(1);}// 等待线程结束thread.wait();return a.exec();
}

        在这个示例中,MyThread 类继承自 QThread,并重写了 run() 函数。在 main() 函数中,我们创建了 MyThread 的实例 thread,并通过 start() 启动了一个新线程。同时,主线程继续执行其他任务。

三、QThread 类的一些关键特性和用法

1、创建线程

         通过继承 QThread 类,可以创建一个自定义的线程类。在自定义的类中,可以重写 run() 函数,该函数定义了线程的执行体。

class MyThread : public QThread {
public:void run() override {// 线程的执行体}
};

2、启动线程

        使用 start() 函数来启动线程。一旦调用了 start()run() 函数将在新线程中执行。

MyThread thread;
thread.start();

3、等待线程结束

        使用 wait() 函数来等待线程执行结束。这确保主线程等待子线程完成后再继续执行。

thread.wait();

4、线程间通信

        Qt 提供了信号和槽机制,可以用于在线程之间进行安全的通信。在多线程中,使用信号和槽是一种避免共享资源问题的方式。

connect(sender, SIGNAL(sendMessage(QString)), receiver, SLOT(receiveMessage(QString)));

5、线程安全

  QThread 提供了一些方法来确保线程的安全性,如 mutexatomic 操作,以避免多线程竞争条件。

QMutex mutex;
mutex.lock();
// 线程安全的操作
mutex.unlock();

四、Qthread注意事项

        在使用 QThread 进行多线程编程时,有一些注意事项需要考虑,以确保正确、安全、高效地使用线程。以下是一些关键的注意事项:

1、不要直接调用 run 函数

        QThread 中的 run() 函数是线程执行体,但不应该直接调用它。正确的方式是通过 start() 函数启动线程,run() 函数会在新线程中自动执行。

// 错误的方式
MyThread thread;
thread.run(); // 不要这样调用// 正确的方式
MyThread thread;
thread.start(); // 通过 start 函数启动线程

2、避免直接继承 QThread

        直接继承 QThread 并重写 run() 函数是一种方式,但并不总是最好的。推荐使用组合的方式,将线程逻辑放在另外的类中,然后在 QThread 的子类中创建该类的实例。

class Worker : public QObject {Q_OBJECT
public slots:void doWork() {// 线程的执行体}
};class MyThread : public QThread {
public:void run() override {Worker worker;connect(this, &MyThread::startWork, &worker, &Worker::doWork);emit startWork();}signals:void startWork();
};

3、线程安全

        考虑多线程访问共享资源时的线程安全性。使用互斥锁 (QMutex) 或其他同步机制来确保对共享数据的访问是线程安全的。

QMutex mutex;
mutex.lock();
// 访问共享资源
mutex.unlock();

4、注意内存管理

        在多线程环境中,注意内存管理问题。确保在合适的时候释放线程中创建的资源,以避免内存泄漏。

5、合理设置线程属性

        使用 setObjectName() 为线程设置名称,以方便调试。可以使用 setPriority() 设置线程的优先级,但要注意过度使用优先级可能导致不稳定的行为。

MyThread thread;
thread.setObjectName("WorkerThread");
thread.setPriority(QThread::LowPriority);


6、不要在主线程中直接操作子线程的对象

        子线程的对象应该通过信号和槽来进行通信。在主线程中直接操作子线程的对象可能导致线程安全问题。

// 错误的方式
MyThread thread;
Worker worker;
worker.doWork(); // 避免在主线程中直接调用子线程对象的函数// 正确的方式
MyThread thread;
Worker worker;
connect(&thread, &MyThread::startWork, &worker, &Worker::doWork);
thread.start();

五、总结

        QThread 是 Qt 中处理多线程编程的基础,并提供了一些辅助工具和机制,以简化开发者在并发环境中的工作。但在某些情况下,使用 QtConcurrentQt Concurrent 命名空间中的高级功能可能更为方便。这些功能提供了更高层次的抽象,用于并发和并行处理。

        Qt C++ 提供了强大而灵活的多线程支持,使得多线程编程变得更加容易。通过 QThread 类的使用,开发者能够轻松创建和管理多线程应用。同时,信号和槽机制为线程间的通信提供了一种安全而高效的方式。

相关文章:

【QT学习十一】QThread

一、引言 在现代软件开发中&#xff0c;多线程编程变得越来越重要&#xff0c;尤其是对于需要处理并发任务的应用程序。Qt C 框架提供了强大的多线程支持&#xff0c;使得开发者能够轻松地创建和管理多线程应用。 在 Qt 中&#xff0c;多线程的实现主要基于 QThread 类。QThrea…...

Mybatis 39_使用MBG生成代码

此2个插件均未晚装成功!!!! 安装 MyBatipse插件 MyBatipse插件 - 开发MyBatis应用的Eclipse插件- 自动完成- 有效性验证- Mapper视图使用MBG MyBatis Generator (MBG):根据底层数据表来自动生成Mapper组件只要两步即可: (1) 提供一个简单的配置文件,告诉MBG连接数据…...

Hudi metadata table(元数据表)

什么是metadata表 Metadata表即Hudi元数据表,是一种特殊的Hudi表,对用户隐藏。该表用于存放普通Hudi表的元数据信息。Metadata表包含在普通Hudi表内部,与Hudi表是一一对应关系。 元数据表的作用 ApacheHudi元数据表可以显著提高查询的读/写性能。元数据表的主要目的是消…...

提高iOS App开发效率的方法

引言 随着智能手机的普及&#xff0c;iOS App开发成为越来越受欢迎的技术领域之一。许多人选择开发iOS应用程序来满足市场需求&#xff0c;但是iOS App开发需要掌握一些关键技术和工具&#xff0c;以提高开发效率和质量。本文将介绍一些关键点&#xff0c;可以帮助你进行高效的…...

MPU机制与实现详解

目录 MPU机制与实现详解 Partition元素-MPU Partition实现元素OSApplication Partition元素-RTE MPU机制与实现详解 1、freedom from interference 此概念来自ISO26262-1&#xff1a;多个元素之间没有可能导致违反安全目标的级联故障&#xff0c;称之为免于干涉。 在左侧的…...

pom文件冲突引起的Excel无法下载

问题一&#xff1a;之前生产环境上可以进行下载Excel的功能突然不能用了 报错提示信息&#xff1a; NoClassDefFoundError: Could not initialize class org.apache.poi.xssf.usermodel.XSSFWorkbook&#xff0c; 在最开始初始化的时候找不到对应的类&#xff0c;虽然我的Libr…...

【HarmonyOS4.0】第十篇-ArkUI布局容器组件(二)

三、层叠布局容器&#xff08;Stack&#xff09; 堆叠容器组件 Stack的布局方式是把子组件按照设置的对齐方式顺序依次堆叠&#xff0c;后一个子组件覆盖在前一个子组件上边。 注意&#xff1a;Stack 组件层叠式布局&#xff0c;尺寸较小的布局会有被遮挡的风险&#xff0c; …...

PLECS如何下载第三方库并导入MOSFET 的xml文件,xml库路径添加方法及相关问题

1. 首先xml库的下载&#xff0c;PLECS提供了一个跳转的链接。 https://www.plexim.com/download/thermal_models 2. 下载一个库&#xff08;以最后一个Wolfspeed为例&#xff0c;属于CREE的SiC MOSFET&#xff09; 下载这个就行&#xff0c;都包含了。不信自己可以试试再下载…...

使用emu8086实现——子程序的设计

一、实验目的 学习子程序的结构、特点&#xff0c;以及子程序的设计和调试方法 二、实验内容 1、从字符串中删除一个字符&#xff0c;并存储到寄存器AX中。 代码及注释&#xff1a; data segmentstring db exas ;字符串内容leng dw $-string ; 字符串长度key db x …...

快速排序、归并排序、希尔排序(2023-12-25)

参考文章 十大经典排序算法总结整理_十大排序算法-CSDN博客 推荐文章 算法&#xff1a;归并排序和快排的区别_归并排序和快速排序的区别-CSDN博客 package com.tarena.test.B20; import java.util.Arrays; import java.util.StringJoiner; public class B25 { static i…...

Qt SDL2播放Wav音频

这里介绍两种方法来实现Qt播放Wav音频数据。 方法一&#xff1a;使用QAudioOutput pro文件中加入multimedia模块。 #include <QApplication> #include <QFile> #include <QAudioFormat> #include <QAudioOutput>int main(int argc, char *argv[]) {…...

[ACM学习] 动态规划基础之一二三维dp

课内学习的动态规划 有记忆的迭代 优化解的结构&#xff1a;原始问题的一部分解是子问题的解 三要素&#xff1a;1.子问题 2.状态的定义 3.状态转移方程 定义 线性dp的一道例题 dp[i]表示以位置 i 结尾的方案总数&#xff0c;dp[4]2&#xff0c;因为&#xff1a;首先只放一…...

Qt点击按钮在其附近弹出一个窗口

效果 FS_PopupWidget.h #ifndef FS_POPUPWIDGET_H #define FS_POPUPWIDGET_H#pragma once#include <QToolButton> #include <QWidgetAction> #include <QPointer>class QMenu;class FS_PopupWidget : public QToolButton {Q_OBJECTpublic:FS_PopupWidget(QW…...

Springboot注解@Configuration和@Bean注解作用,生命周期

简介&#xff1a; Configuration 类是定义 bean 配置的地方&#xff0c;而 Bean 方法是具体创建 bean 实例的方法。 Configuration 作用&#xff1a; Configuration 注解用于定义配置类&#xff0c;表明该类包含一个或多个 bean 定义的方法。Spring 容器在启动时会自动扫描这些…...

30天精通Nodejs--第十五天:Websocket

引言 这里我们将继续深入探讨另一项强大且实时性极高的网络通信技术——WebSocket。通过本篇文章,将全面了解如何在Node.js环境中利用WebSocket实现服务端与客户端之间双向、低延迟的数据传输,并掌握其基础用法以及一些高级应用场景。 基础用法 安装WebSocket库 在Node.j…...

C++深入学习之STL:2、适配器、迭代器与算法部分

适配器概述 C标准模板库(STL)中提供了几种适配器&#xff0c;这些适配器主要用于修改或扩展容器类的功能。STL中的适配器主要包括以下几种&#xff1a; 1、迭代器适配器&#xff1a;迭代器适配器提供了一种机制&#xff0c;可以将非迭代器对象转换为迭代器对象。比如back_ins…...

Tiktok/抖音旋转验证码识别

一、引言 在数字世界的飞速发展中&#xff0c;安全防护成为了一个不容忽视的课题。Tiktok/抖音&#xff0c;作为全球最大的短视频平台之一&#xff0c;每天都有数以亿计的用户活跃在其平台上。为了保护用户的账号安全&#xff0c;Tiktok/抖音引入了一种名为“旋转验证码”的安…...

【Java 设计模式】设计原则

文章目录 ✨单一职责原则&#xff08;SRP&#xff09;✨开放/封闭原则&#xff08;OCP&#xff09;✨里氏替换原则&#xff08;LSP&#xff09;✨依赖倒置原则&#xff08;DIP&#xff09;✨接口隔离原则&#xff08;ISP&#xff09;✨合成/聚合复用原则&#xff08;CARP&#…...

Druid连接池工具公式化SQL附踩坑记录

1. 需求 使用Druid连接池工具格式化sql用于回显时候美观展示 2. 代码示例 2.1 依赖 <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.6</version> </dependency> 2.2 ParseUtils…...

Linux内核--网络协议栈(二)UDP数据包发送

目录 一、引言 二、数据包发送 ------>2.1、数据发送流程 三、协议层注册 ------>3.1、socket系统调用 ------>3.2、socket创建 ------>3.3、协议族初始化 ------>3.4、对应协议的socket创建 ------>3.5、协议注册 四、通过套接字发送网络数据 --…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...