线程和QObjects

news2024/9/24 17:17:55

QObject的可重入性: 

QThread继承了QObject,它发出信号以指示线程开始或完成执行,并提供一些插槽。

QObjects可以在多个线程中使用发出调用其他线程中槽的信号,并将事件发布到在其他线程中“活动”的对象。这是可能的,因为允许每个线程都有自己的事件循环。

QObject是可以重入的。它的绝大数非GUI子类,如QTimer,QTcpSocket,QUdpSocket和QProcess,都是可以重入的,使得可以从多个线程同时使用这些类。

注意:这些类要在从单个线程中创建和使用,在一个线程中创建对象并从另一个线程调用其函数不能保证有效。需要注意以下3点:

  • 必须始终在父级的线程中创建QObject的子级,意味着,除其他事项外,永远不应该将QThread对象(this)作为在线程中创建的对象的父级传导(因为QThread对象本身在另一个线程中创建的)
  • 事件驱动对象自能在单一的线程中使用。具体来说,这适用于的定时器和网络模块,例如不可在对象所在线程中QObject::thread()以外的其他线程中启动一个定时器或连接一个套接字。
  • 必须确保删除QThread对象以前删除在该线程中创建的所有对象,可以通过在run()函数中的栈上创建对象来确保这一点

虽然QObject是可重入的,但GUI类,特别是QWidget以及其子类,都是不是可重入的,它们只能从主线程中使用QCoreApplication::exec()也需要在主线程中调用。

实际上,可以通过将耗时的操作放在单独的工作线程中并在工作线程完成后在主线程的屏幕上显示结果, 可以轻松解决在主线程以外的其他线程中使用 GUI 类的不可能性。

通常,不支持在 QApplication 之前创建 QObjects,这可能会导致退出时出现奇怪的崩溃,具体取决于平台。这意味着 QObject 的静态实例也不受支持的。结构合理的单线程或多线程应用程序应使 QApplication 成为第一个创建,最后一个销毁的 QObject。

每个线程的事件循环:

每个线程都可以有自己的事件循环。

初始线程使用 QCoreApplication::exec() 启动其事件循环,或者对于单对话框 GUI 应用程序,有时使用 QDialog:exec()。其他线程可以使用 QThread::exec() 启动事件循环。与QCoreApplication一样,QThread提供了一个exec()函数和一个quit()插槽。

线程中的事件循环使线程可以使用某些需要存在事件循环的非 GUI Qt 类,它还可以将来自任何线程的信号连接到特定线程的插槽。

 QObject实例被称为驻留在创建它的线程中。该对象的事件由该线程的事件循环调度,QObject中的线程可以使用QObject::thread()使用。可以使用QObject::moveToThread()函数更改对象其子线程相关性。

从拥有对象的线程以外的线程调用QObject是不安全的,除非能保证该对象当时不处理事件。改用QObject::deleteLater(),将发布一个DeferredDelete事件,对象线程的事件循环最终将拾取该事件。默认情况下,拥有 QObject 的线程是创建 QObject 的线程,但在调用QObject::moveToThread() 之后则不是

如果未运行任何事件循环,则不会将事件传递到对象。例如,如果您在线程中创建了一个 QTimer 对象,但从不调用 exec(),则 QTimer 将永远不会发出其 timerout() 信号。调用 deleteLater 也不起作用。(这些限制也适用于主线程。)

所有线程都支持事件过滤器,但限制是监视对象必须与受监视对象位于同一线程中.

从其他线程中访问QObject子类:

QObject 和它所有的子类都不是线程安全的,这包括整个事件传递系统。需要时刻记着,正在从其他线程中访问一个对象时,事件循环可能正在向这个对象传递事件。

如果调用一个没有在当时线程中的QObject子类的函数,而这个对象有可能会获取事件,那么就必须使用mutex来保护对这个QObject子类的内部数据的所有访问,否者,可能出现崩溃或则其他以外行为。

与其他对象像是,QThread对象,居住于常见该对象的线程。在QThread子类中提供槽一般时不安全的,除非使用mutex来保护成员变量。但是,可以安全地在Qthread::run函数中发射信号,因为信号发射是线程安全的。

跨越线程的信号与槽:

Qt支持以下信号与槽连接类型

可已通过向connect()函数传递附加的参数来指定关联类型,注意,如果在接收者线程中由一个事件循环,那么当发送者与接收者在不同的线程中时,使用Direct Connection是不安全的,类似的,调用其他线程中的对象的任何函数也是不安全的。

 QObject::connect() 是线程安全的

  • Auto Connection(自动连接,默认),如果在接收对象具有关联的线程中发出信号,则行为与直接连接相同。否则,该行为与排队连接相同。
  • Dirct Connection(直接连接)会立即调用该插槽。插槽在发射器的线程中执行,该线程不一定是接收器的线程。
  • Queued Connection(排队连接)当控制返回到接收器线程的事件循环时,将调用该槽。该插槽在接收器的线程中执行。
  • Blocking Queued Connection(阻止排队连接)
  • 该槽的调用方式与排队连接一样,但当前线程块除外,直到槽返回。(使用此类型连接同一线程中的对象将导致死锁。)
  • Unique Connection(唯一连接)该行为与自动连接相同,但仅当它不复制现有连接时,才会建立连接。即,如果同一信号已经连接到同一对对象的同一插槽,则不会建立连接并且 connect() 

参考文档:

Threads and QObjects | Qt 5.15

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

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

相关文章

redis可视工具AnotherRedisDesktopManager的使用

redis可视工具AnotherRedisDesktopManager的使用 简介 Another Redis DeskTop Manager 是一个开源项目,提供了以可视化的方式管理 Redis 的功能,可供免费下载安装,也可以在此基础上进行二次开发,主要特点有: 支持 W…

Matlab中安装NURBS工具箱及使用

文章目录前言一、NURBS工具箱的安装1 打开matlab,点击附加功能2 输入nurbs3 下载后压缩包解压4 将解压后的文件夹放到matlab文件夹的toolbox文件夹里面5 选择“预设路径”上方的“预设”二、NURBS工具箱的使用2.1 NURBS 结构:2.2 对NURBS工具箱的初步理解…

关于表的操作 数据库(3)

目录 前期准备工作: 一、单表查询: 二、多表查询: 前期准备工作: 修改数据库的配置文件,,使其可以显示库名,其中//d代表当前使用的数据库名 注:vim /etc/my.cnf.d/mysql-server.c…

Session与Cookie的区别(四)

咖啡寄杯的烦恼 虽然店里生意还可以,但小明无时无刻不想着怎么样发大财赚大钱,让店里的生意变得更好。 他观察到最近好多便利商店开始卖起了咖啡,而且时不时就买一送一或是第二件半价,并且贴心地提供了寄杯的服务。 寄杯就是指说你…

《剑指offer》:数组部分

一、数组中重复的数字题目描述:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1…

C语言fscanf和fprintf函数的用法详解

fscanf() 和 fprintf() 函数与前面使用的 scanf() 和 printf() 功能相似,都是格式化读写函数,两者的区别在于 fscanf() 和 fprintf() 的读写对象不是键盘和显示器,而是磁盘文件。这两个函数的原型为:int fscanf ( FILE *fp, char …

【力扣-LeetCode】1138. 字母板上的路径-C++题解

1138. 字母板上的路径难度中等98收藏分享切换为英文接收动态反馈我们从一块字母板上的位置 (0, 0) 出发,该坐标对应的字符为 board[0][0]。在本题里,字母板为board ["abcde", "fghij", "klmno", "pqrst", &quo…

点云转3D网格【Python】

推荐:使用 NSDT场景设计器 快速搭建 3D场景。 在本文中,我将介绍我的 3D 表面重建过程,以便使用 Python 从点云快速创建网格。 你将能够导出、可视化结果并将结果集成到您最喜欢的 3D 软件中,而无需任何编码经验。 此外&#xff0…

总投资超500亿,广州白云机场三期扩建工程的IT投资更吸引人

【科技明说 | 每日看点】2023年基建大工程计划出台,广州白云机场三期将落实百亿元投资引发业内关注。据悉,广州白云机场三期扩建工程投资达537.7亿元,计划于2025年建成投产。这是中国民航历史上规模最大的改扩建工程,其扩建工程今…

TC3xx FlexRay™ 协议控制器 (E-Ray)-01

1 FlexRay™ 协议控制器 (E-Ray) E-Ray IP 模块根据为汽车应用开发的 FlexRay™ 协议规范 v2.1 执行通信【performs communication according to the FlexRay™ 1) protocol specification v2.1】。使用最大指定时钟,比特率可以编程为高达 10 Mbit/s 的值。连接到物…

Fluent Python 笔记 第 5 章 一等函数

在 Python 中,函数是一等对象。编程语言理论家把“一等对象”定义为满足下述条件的程 序实体: 在运行时创建能赋值给变量或数据结构中的元素 • 能作为参数传给函数能作为函数的返回结果 5.1 把函数视作对象 会用 map。 5.2 高阶函数 接受函数为参数&#xff0…

基于JAVA的超级玛丽设计与实现

技术:Java等摘要:随着计算机技术及网络技术的不断发展,电子游戏越来越普及。经典游戏“超级玛丽”因其本身所具有的娱乐性与教育意义而被人们广泛接受,在广大的青少年玩家中享有极高的知名度。Java语言作为一种完全面向对象的程序…

【AI 交互式聊天】无需等待 Bing ChatGPT : 已经有一个基于搜索结果响应的 AI 交互式聊天网站了!Perplexity

Perplexity: https://www.perplexity.ai 同样的问题,我问ChatGPT,回答如下: 实现财富自由需要一系列的步骤和策略,以下是一些建议: 1. 设定目标:明确你的财务目标,并制定一个有目标的计划来实…

吾爱破解2023安卓中级题

先来看看APP界面 拖到jadx,see see java 源码 关键是要让代码跳转到这里,我这里主要是修改smali,然后重新签名打包,当然,你也可以用frida或者objection hook 传参 模仿下面的两行代码,在位置1插入 :cond_6…

循环队列来了解一下!!

笔者在之前的一篇文章,详细的介绍了:队列之单向链表与双向链表的模拟实现:https://blog.csdn.net/weixin_64308540/article/details/128742090?spm1001.2014.3001.5502 感兴趣的各位老铁,可以参考一下啦!下面进入循环…

基于Java+SpringBoot+Vue前后端分离酒店管理系统设计与实现

博主介绍:✌全网粉丝3W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建、毕业项目实战、项目定制✌ 博主作品:《微服务实战》专栏是本人的实战经验总结,《S…

linux系统常用命令

目录 一、系统介绍 二、Linux常用命令 1、Linux命令格式 2、文件目录操作命令:ls 3、文件目录操作命令:cd 4、文件目录操作命令:cat 5、文件目录操作命令:more 6、文件目录操作命令:tail 7、创建文件命令&…

【三维点云】01-激光雷达原理与应用

文章目录内容概要1 激光雷达原理1.1 什么是激光雷达?1.2 激光雷达原理1.3 激光雷达分类三角法TOF法脉冲间隔测量法幅度调制的相位测量法相干法激光雷达用途2 激光雷达安装、标定与同步2.1 激光雷达安装方式考虑因素2.2 激光雷达点云用途2.3 数据融合多激光雷达数据融…

Rust学习入门--【7】Rust 数据类型

类型系统 对于任何一门语言都是重中之重,因为它体现了语言所支持的不同类型的值。 类型系统 也是 IT 初学者最难啃的三座大山之一,而类型系统之所以难以理解,主要是没有合适的现成的参考体系。 我们说类型系统 存在的目的,就是 …

【代码随想录】-动态规划专题

文章目录理论基础斐波拉契数列爬楼梯使用最小花费爬楼梯不同路径不同路径 II整数拆分不同的二叉搜索树背包问题——理论基础01背包二维dp数组01背包一维数组(滚动数组)装满背包分割等和子集最后一块石头的重量 II目标和一和零完全背包零钱兑换 II组合总和…