【Qt高级】QThread与QTimer组合使用引出的信号槽执行在哪个线程的思考【2023.08.06】

源码见 testQThread_QTimer…

Qt 版本5.6.3
视频讲解:https://www.bilibili.com/video/BV15P411C79i/
链接: 视频讲解

简介

  想法很单纯,就是主线程启动一个子线程,子线程里启动一个定时器,定时执行一些任务,然鹅实际开发中警告不断。😒Qt

警告内容有:

1.QObject: Cannot create children for a parent that is in a different thread.

2.QObject::killTimer: Timers cannot be stopped from another thread

3.QObject::moveToThread: Cannot move objects with a parent

对线程和线程对象的理解

  线程对象是一个内核对象,就和常用的打开文件会获得一个文件句柄的句柄都属于稀缺的资源。线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个进程可以包含多个线程,每个线程可以并发执行不同的任务。

  一个进程一定有一个主线程,子线程是从主线程启动的。线程的关键特性除了并发性其实还有一个比较隐晦,就是线程的模块性。这是因为线程执行内容总应该是负责某块功能,具有一定独立性。举例来说,main.exe启动一个独立的线程来定时检查更新,显然这个线程负责的功能就很明确,如果更新检查除了问题,就检查这个线程涉及的所有代码。

  线程的退出:一般情况,线程干完活就自动释放了。还是拿上面的检查线程来说,如果他的使命是检查5次是否有更新,则检查完5次,没干的了,这个线程就会退了。除非是一直检查,这个线程才会一直运行下去。

关于QThread

  QThread这个类封装了对线程对象的管理,相当于我们雇佣了一个工人,需要发个工牌来知道都有哪些工人,通过工牌的工号发布指令。显然,如果只有一个主线程就不需要了,因为系统已经干了。

  具体到QThread的用法,主流的就2种。后续有代码解析。

方法一:继承QThread,并重写run方法、

方法二:将代码逻辑封装为一个类,

关于QTimer

  QTimer用于执行一些定时任务,往往采用信号槽的方式,连接timeout()函数至槽函数。

  QTimer的启动、停止、创建、销毁都需在同一个线程中。主线程中用的很easy,一旦涉及到子线程使用难度就上来了,需要保证QTimer的创建、启动、停止、销毁都是在同一线程。而往往我们都是在各种槽函数中对定时器停止。

Qt 槽函数到底执行在哪个线程?

  解决开篇警告的核心是搞清楚槽函数执行在哪个线程,以及为啥执行在那个线程。

这个答案来于互联网,然而我实测的结果不是这样的。

在多线程的Qt程序中,一个槽函数的执行线程是由发出信号的线程决定的,而不是连接该信号的线程。

具体来说:

  1. 如果信号是在主线程发出的,则槽函数会在主线程执行,即使该槽函数是在其他线程中连接的。
  2. 如果信号是在非GUI线程发出的,则槽函数会在该非GUI线程执行,即使是在主线程中连接的。
  3. 槽函数总是会在信号发出的线程中执行。

** 构造函数的执行顺序

  看似简单,我只要保证emit是在哪个线程即可。但实际开发中涉及类的组合关系,A类的成员类B类,在调用A类的构造之前会先调用B类的构造,B类的构造,而B类的构造还是在上一级的线程中。这也就导致了类A被moveToThread之后成了线程m_thred的资源,而A的B成员则还是主线程的资源。

class CB{
public:CB(){}
private:
}
class CA{
public:CA(){ moveToThread(&m_thread); }
private:CB m_b; QThread m_thread;
}

总结

  槽函数执行在哪个线程取决于发出信号的对象和槽函数的对象是在哪个线程构造的。要想保证成员类的槽函数都执行在子线程,成员类的构造就需在子线程,也就是成员类要以指针的方式组合,在合适的时机new对象出来。

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

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

相关文章

Yolov5缺陷检测/目标检测 Jetson nx部署Triton server

使用AI目标检测进行缺陷检测时,部署到Jetson上即小巧算力还高,将训练好的模型转为tensorRT再部署到Jetson 上供http或GRPC调用。1 Jetson nx 刷机 找个ubuntu 系统NVIDIA官网下载安装Jetson 的sdkmanager一步步刷机即可。 本文刷的是JetPack 5.1, 其中包…

Oracle日志相关操作

1.归档日志设置 # 切换账号 $ su - oracle# 登录oracle的sys账户 $ sqlplus / as sysdbasql> archive log list; #查看是不是归档方式 SQL> archive log list; Database log mode Archive Mode Automatic archival Enabled Archive destin…

【Windows】Windows开机密码重置

文章目录 前言一、问题描述二、操作步骤2.1 安装DaBaiCai_d14_v6.0_2207_Online.exe2.2 插入U盘2.3 打开大白菜,点击“一键制作USB启动盘”2.4 等待进度条走完2.5 重启电脑,开机按“F12”或者“F8”(具体百度一下,对应品牌电脑开机…

笔试数据结构选填题

目录 卡特兰数Catalan:出栈序列/二叉树数 树 二叉树 N01N2 哈夫曼树(最优二叉树)Huffman 度m的哈夫曼树只有度为0和m的结点:Nm(n-1)/(m-1) 平衡二叉树AVL Nh表示深度为h最少结点数,则N00,N11&#…

网络防御(7)

课堂实验 R1 [Huawei] int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip add 100.1.12.2 24 protocolAug 1 2023 10:24:09-08:00 Huawei gOlIFNET/4/LINK STATE(1)[4]:The1ineIp on the interface GigabitEthernet0/0/0 has entered the Up state. [Huawei-GigabitEthernet0/0/…

SpringBoot 底层机制分析【Tomcat 启动+Spring 容器初始化+Tomcat 如何关联Spring 容器】【下】

😀前言 本篇博文是关于SpringBoot 底层机制分析实现,希望能够帮助你更好的了解SpringBoot 😊 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大…

Linux 查找某个目录下所有文件中是否含有某些字符串

使用如下命令进行查找: find . -name "*" | xargs grep -n --color "hello"查找当前目录下所有文件,找出含有字符串 “hello” 的文件并显示行号。 在~/.bashrc 中添加如下函数: function finds(){if [ -z $1 ];thene…

Leetcode.1559 二维网格图中探测环

题目链接 Leetcode.1559 二维网格图中探测环 rating : 1838 题目描述 给你一个二维字符网格数组 g r i d grid grid ,大小为 m x n ,你需要检查 g r i d grid grid 中是否存在 相同值 形成的环。 一个环是一条开始和结束于同一个格子的长度 大于等于…

lc137. 只出现一次的数字 II

数组排序,既和前不一样又和后不一样的就是唯一的一个 public static int numberOnce(int[] nums) {Arrays.sort(nums);if (nums.length > 2 && nums[0] ! nums[1]) {//避免只有一个元素的数组return nums[0];}if (nums.length > 2 && nums[nu…

PPTP应用案例:让你的网络不再受限

嗨,小伙伴们,作为一家专业的PPTP代理供应商,我们深知网络安全对于每个人的重要性。今天,我将与大家分享一些关于PPTP的应用案例,借此帮助大家更好地了解PPTP的实际应用和专业性。无论你是在公共Wi-Fi上冲浪&#xff0c…

使用MyBatis操作数据库

hi,大家好,今天为大家带来MyBatis操作数据库的知识 文章目录 🐷1.根据MyBatis操作数据库🧊1.1查询操作🍇1.1.1无参查询🍇1.1.2有参查询 🧊1.2删除操作🧊1.3修改操作🧊1.4增加操作🧊…

Windows 安装 pandoc 将 jupyter 导出 pdf 文件

Windows 安装 pandoc 将 jupyter 导出 pdf 文件 1. 下载 pandoc 安装文件2. 安装 pandoc3. 安装 nbconvert4. 使用 pandoc 1. 下载 pandoc 安装文件 访问 https://github.com/jgm/pandoc/releases,下载最新版安装文件,例如,3.1.6.1 版&#…

【Redis面试题整理一】

一、Redis定义 Redis 是一种基于内存的数据库,对数据的读写操作都是在内存中完成,读写速度非常快,被广泛应用于缓存方向。并且,Redis 存储的是 KV 键值对数据。 二、Redis为什么不存在并发竞争 对数据类型的操作都是原子性的&a…

spring-boot webservice的例子

webservice发布服务 源码下载地址 spring-boot-webservice例子资源-CSDN文库 webservice cilent调用 源码下载地址 spring-boot-clintwebservice调用服务的例子资源-CSDN文库

jackson自定义序列化反序列化

jackson自定义序列化和反序列化 自定义序列化 序列化主要作用在返回数据的时候以BigDecimal统一返回3位小数为例自定义序列化处理类继承jackson的JsonSerializer类,重写serialize方法 /*** author liouwb*/ public class BigDecimalSerializer extends JsonSeria…

Web安全——Burp Suite基础上

Burp Suite基础 一、Burp Suite安装和环境配置如何命令行启动Burp Suite 二、Burp Suite代理和浏览器设置FireFox设置 三、如何使用Burp Suite代理1、Burp Proxy基本使用2、数据拦截与控制3、可选项配置Options客户端请求消息拦截服务器端返回消息拦截服务器返回消息修改正则表…

面试题更新之-this指向问题

文章目录 this指向是什么常见情况下 this 的指向怎么修改this的指向 this指向是什么 JavaScript 中的 this 关键字用于引用当前执行代码的对象。它的指向是动态的,根据执行上下文的不同而变化。 常见情况下 this 的指向 全局作用域中的 this: 在全局作…

内网横向移动—WinLinux内存离线读取Hashcat破解RDPSSH存储提取

内网横向移动—Win&Linux&内存离线读取&Hashcat破解&RDP&SSH存储提取 1. 前言2. Windows系统密码提取2.1. 在线读取2.2. 离线读取2.2.1. 无存储读取2.2.1.1. 读取文件2.2.1.2. 本地解密 2.2.2. 有存储读取 2.3. 解决高版本2.3.1. 修改注册表2.3.2. 重新登陆…

分布式Redis详解

目录 前言安装redis的俩种方法Redis 与 MySQL的区别Redis可以实现那些功能Redis常用的数据类型有序列表的底层是如何实现的?什么是跳跃表 Redis在Spring中的使用Redis 中为什么单线程比多线程快Redis的分布式锁如何实现Redis 分布式锁可能出现的问题Redis保持数据不丢失的方式…

掌握C语言输入技巧:getchar()函数消除回车符困扰

在C语言编程的旅程中,你可能会遇到一个令人困惑的情况:使用getchar()函数获取字符时,那讨厌的回车符(\n)又是如何产生和处理的呢?本文将为你揭示这个问题,并分享几种消除回车符困扰的经验。 一…