【QT 多线程示例】两种多线程实现方式

文章目录

  • 多线程实现
    • 方式一:继承QThread类
    • 方式二: 使用QObject::moveToThread()方法

多线程实现

在Qt中,实现多线程编程有两种常见的方式,它们分别是通过继承QThread类和使用QObject::moveToThread()方法。

方式一:继承QThread类

通过继承QThread类并重写其run()方法,可以在新线程中执行特定的任务。

具体步骤

  1. 创建自定义线程类:继承QThread类,并重写run()方法。在run()方法中编写需要在新线程中执行的代码。

  2. 创建线程对象:在主线程中创建自定义线程类的实例。

  3. 启动线程:调用线程对象的start()方法启动线程。此时,Qt会创建一个新的线程,并在该线程中调用run()方法。

  4. 线程间通信:可以通过信号和槽机制在主线程和子线程之间进行通信。自定义线程类可以发射信号,主线程可以连接这些信号到相应的槽函数,以处理线程返回的数据或状态。

示例代码
https://github.com/BinaryAI-1024/QtStudy/tree/master/thread/createThread1

// mythread.h
#include <QThread>
#include <QDebug>class Mythread: public QThread{Q_OBJECT
public:explicit Mythread(QObject *parent = nullptr);void run();};
// mythread.cpp
#include "Mythread.h"Mythread::Mythread(QObject *parent) : QThread(parent)
{}void Mythread::run(){// 在新线程中执行的代码for (int i = 0; i < 5; ++i) {qDebug() << "Worker thread is running... (" << i << ")";QThread::sleep(1); // 模拟耗时操作}
}
//main.cpp
#include <QCoreApplication>
#include "Mythread.h"
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);Mythread thread1;thread1.start();for (int i = 0; i < 5; ++i) {qDebug() << "Main thread is running... (" << i << ")";QThread::sleep(1); // 模拟耗时操作}thread1.wait(); // 等待直到thread1线程结束return a.exec();
}

运行结果:

Main thread is running... ( 0 )
Worker thread is running... ( 0 )
Worker thread is running... ( 1 )
Main thread is running... ( 1 )
Worker thread is running... ( 2 )
Main thread is running... ( 2 )
Worker thread is running... ( 3 )
Main thread is running... ( 3 )
Main thread is running... ( 4 )
Worker thread is running... ( 4 )

优缺点分析

  • 优点:实现简单,适合需要在新线程中执行单一任务的场景。

  • 缺点

    • 强制将业务逻辑与线程控制代码耦合在一起,不利于代码的复用和维护。
    • 需要手动管理线程的生命周期,增加了代码的复杂性。

方式二: 使用QObject::moveToThread()方法

通过将QObject(或其子类)的实例移动到新线程中,可以在该线程中执行该对象的方法。这种方法更加灵活,不需要继承QThread类。

具体步骤

  1. 创建工作对象:定义一个继承自QObject的类,并在其中定义需要在新线程中执行的方法(槽函数)。

  2. 创建线程对象:在主线程中创建一个QThread实例。

  3. 移动对象到线程:调用工作对象的moveToThread()方法,将其移动到新创建的线程中。

  4. 启动线程并调用槽函数

    • 调用线程对象的start()方法启动线程。
    • 使用信号和槽机制,在主线程中发射信号,触发工作对象在新线程中执行的槽函数。
  5. 线程间通信:同样可以通过信号和槽机制在主线程和工作线程之间进行通信。工作线程可以发射信号,主线程连接这些信号到相应的槽函数,以处理线程返回的数据或状态。

示例代码
https://github.com/BinaryAI-1024/QtStudy/tree/master/thread/createThread2

//myworker.h
#include <QObject>
class MyWorker : public QObject
{
public:explicit MyWorker(QObject *parent = nullptr);void working();};
//myworker.cpp
#include <QDebug>
#include <QThread>
#include "myworker.h"MyWorker::MyWorker(QObject *parent) : QObject(parent)
{}void MyWorker:: working(){// 在新线程中执行的代码for (int i = 0; i < 5; ++i) {qDebug() << "Worker thread is running... (" << i << ")";QThread::sleep(1); // 模拟耗时操作}}
//main.cpp
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include "myworker.h"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);QThread thread1;MyWorker worker;// 将 worker 对象移动到 thread1 线程中,以便 working 函数在 thread1 中执行worker.moveToThread(&thread1);// 连接 QThread 的 started 信号到 MyWorker 的 working 槽函数// 当 thread1 启动时,worker 的 working 函数会被调用QObject::connect(&thread1, &QThread::started, &worker, &MyWorker::working);// 启动 thread1 线程thread1.start();for (int i = 0; i < 5; ++i) {qDebug() << "Main thread is running... (" << i << ")";QThread::sleep(1); // 模拟耗时操作}thread1.wait();return a.exec();
}

运行结果:

Main thread is running... ( 0 )
Worker thread is running... ( 0 )
Worker thread is running... ( 1 )
Main thread is running... ( 1 )
Worker thread is running... ( 2 )
Main thread is running... ( 2 )
Worker thread is running... ( 3 )
Main thread is running... ( 3 )
Main thread is running... ( 4 )
Worker thread is running... ( 4 )

优缺点分析

  • 优点

    • 将业务逻辑与线程控制代码分离,提高了代码的复用性和可维护性。
    • 可以方便地在多个线程之间移动对象,实现复杂的线程间交互。
  • 缺点:实现相对复杂一些,需要额外管理对象在新线程中的生命周期和信号槽连接。

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

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

相关文章

实验5:Vuex状态管理

Web前端开发技术课程实验报告 实验5&#xff1a;Vuex状态管理 一、实验目的&#xff1a; 掌握Vuex的工作原理和5个核心概念。掌握Vuex API接口的使用方法。 二、实验要求&#xff1a; 掌握mutations、actions、getters的定义和使用方法&#xff0c;完成以下实验内容。上交实…

深入解析 Linux 声卡驱动:从架构到实战

在嵌入式 Linux 设备中&#xff0c;音频功能的实现离不开 Linux 声卡驱动。而 ALSA (Advanced Linux Sound Architecture) 作为 Linux 内核的音频框架&#xff0c;提供了一整套 API 和驱动模型&#xff0c;帮助开发者快速集成音频功能。本篇文章以 WM8960 音频编解码器&#xf…

windows+ragflow+deepseek实战之一excel表查询

ragflows平台部署参考文章 Win10系统Docker+DeepSeek+ragflow搭建本地知识库 ragflow通过python实现参考这篇文章 ragflow通过python实现 文章目录 背景效果1、准备数据2、创建知识库3、上传数据并解析4、新建聊天助理5、测试会话背景 前面已经基于Win10系统Docker+DeepSeek+…

【VUE】ant design vue实现表格table上下拖拽排序

适合版本&#xff1a;ant design vue 1.7.8 实现效果&#xff1a; 代码&#xff1a; <template><div class"table-container"><a-table:columns"columns":dataSource"tableData":rowKey"record > record.id":row…

vue3+Ts+elementPlus二次封装Table分页表格,表格内展示图片、switch开关、支持

目录 一.项目文件结构 二.实现代码 1.子组件&#xff08;表格组件&#xff09; 2.父组件&#xff08;使用表格&#xff09; 一.项目文件结构 1.表格组件&#xff08;子组件&#xff09;位置 2.使用表格组件的页面文件&#xff08;父组件&#xff09;位置 3.演示图片位置 ele…

ModBus TCP/RTU互转(主)(从)|| Modbus主动轮询下发的工业应用 || 基于智能网关的串口服务器进行Modbus数据收发的工业应用

目录 前言 一、ModBus TCP/RTU互转&#xff08;从&#xff09;及应用|| 1.1 举栗子 二、ModBus TCP/RTU互转&#xff08;主&#xff09; 2.1 举栗子 三、ModBus 主动轮询 3.1 Modbus主动轮询原理 3.2 Modbus格式上传与下发 3.2.1.设置Modbus主动轮询指令 3.2.2 设…

Elasticsearch 在航空行业:数据管理的游戏规则改变者

作者&#xff1a;来自 Elastic Adam La Roche 数字化客户体验不再是奢侈品&#xff0c;而是欧洲航空公司必不可少的需求。它推动了客户满意度&#xff0c;提升了运营效率&#xff0c;并创造了可持续的竞争优势。随着行业的不断发展&#xff0c;优先投资前沿数字技术和平台的航空…

CXL协议之FM(Fabric Management)解释

CXL协议中的FM功能详解 1. FM的核心作用 FM是CXL&#xff08;Compute Express Link&#xff09;架构中的核心管理实体&#xff0c;负责协调和管理CXL设备之间的通信、资源分配及拓扑结构。其核心功能包括&#xff1a; 设备发现与枚举&#xff1a;识别CXL拓扑中的设备&#x…

html5基于Canvas的经典打砖块游戏开发实践

基于Canvas的经典打砖块游戏开发实践 这里写目录标题 基于Canvas的经典打砖块游戏开发实践项目介绍技术栈核心功能实现1. 游戏初始化2. 游戏对象设计3. 碰撞检测系统4. 动画系统5. 用户界面设计 性能优化1. 渲染优化2. 内存管理 项目亮点技术难点突破项目总结 项目介绍 在这个…

IDEA的常用设置与工具集成

简介 IDEA是捷克JetBrains公司推出的一款Java集成开发环境&#xff0c;在业内被公认为最好的Java开发工具之一&#xff0c;尤其在智能代码助手、代码自动提示、重构、J2EE支持、Ant、Junit、CVS整合、代码审查、创新的GUI设计等方面的功能可以说是超强的。 官网&#xff1a;ht…

Golang | 每日一练 (6)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 Golang | 每日一练 (6)题目参考答案什么是内存逃逸&am…

Qt窗口控件之颜色对话框QColorDialog

颜色对话框QColorDialog QColorDialog 是 Qt 内置的颜色对话框&#xff0c;它允许用户选择一个颜色&#xff0c;并通过接口获取颜色的值&#xff0c;进行进一步设置。 获取QColorDialog颜色 QColorDialog 可以使用堆创建&#xff0c;挂载对象树的方式。但它更适合使用它的静…

Windows Docker 报错: has no HTTPS proxy,换源

pull python 3.7报错&#xff1a; 尝试拉取Docker 测试库hello world也失败 尝试使用临时镜像源&#xff0c;可以成功拉取&#xff1a; sudo docker pull docker.m.daocloud.io/hello-world说明确实是网络问题&#xff0c;需要配置镜像源&#xff0c;为了方便&#xff0c;在d…

Unity Shader 学习16:全局光照 概念理解

- 全局光照 直接光 间接光&#xff0c;在没有开启GI的情况下是不计算间接光的&#xff08;如果放了光照探针 倒是可以模拟间接光 <光照探针只影响动态物体>&#xff09;&#xff1b; - 处理对象&#xff1a;静态物体(static) 、 非静态(动态)物体&#xff1b; - 计算方…

【蓝桥杯python研究生组备赛】005 数学与简单DP

题目1 01背包 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整数&a…

吴恩达机器学习笔记复盘(六)梯度下降算法

简介 梯度下降&#xff08;Gradient Descent&#xff09;是一种常用的优化算法&#xff0c;广泛应用于机器学习、深度学习等领域&#xff0c;在这里是用于求J&#xff08;w,b&#xff09;局部最小值。 我自己觉得这样说有点过于抽象。换个直观点的说法就是&#xff0c;一个人…

【Golang那些事】go1.22和1.23 更新重点及测评

好久没有写文章了&#xff0c;攒了一年的Golang版本特性的技术点以及踩过的坑&#xff0c;那就在新年第一篇的文章中做一个总结吧&#xff1a; 一、关于迭代器 (一)迭代器去掉了共享共享内存 一个经典的面试题 说到Golang经典的面试题&#xff0c;大家可能都刷到过很多&…

【css酷炫效果】纯CSS实现照片堆叠效果

【css酷炫效果】纯CSS实现照片堆叠效果 缘创作背景html结构css样式完整代码基础版进阶版(增加鼠标悬停查看) 效果图 想直接拿走的老板&#xff0c;链接放在这里&#xff1a;https://download.csdn.net/download/u011561335/90492022 缘 创作随缘&#xff0c;不定时更新。 创…

labview与西门子1500plc进行S7通讯(仿真效果)

环境&#xff1a; 1.博图V16 2.S7-PLCSIM Advanced V3.0 3.labview2020 4.HslCommunication的dll文件 运行效果图 通过使用HslCommunication的库文件来对西门子plc进行通讯 labview代码 代码打包 通过网盘分享的文件&#xff1a;labview进行s7通讯测试.rar 链接: https:/…

[蓝桥杯 2023 省 B] 飞机降落(不会dfs的看过来)

[蓝桥杯 2023 省 B] 飞机降落 题目描述 N N N 架飞机准备降落到某个只有一条跑道的机场。其中第 i i i 架飞机在 T i T_{i} Ti​ 时刻到达机场上空&#xff0c;到达时它的剩余油料还可以继续盘旋 D i D_{i} Di​ 个单位时间&#xff0c;即它最早可以于 T i T_{i} Ti​ 时刻…