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

Qt多线程之moveToThread()函数

文章目录

  • 一、moveToThread()执行后,当前代码线程没有改变。
  • 二、对象执行moveToThread()后,哪些成员加入了子线程
    • 1、创建对象时不指定父对象
    • 2、对属性对象使用moveToThread加入子线程作用域
    • 3、将属性对象的创建放到子线程中执行
  • 三、C++内存模型

在使用“继承QObject+QThread”实现多线程时,出现了一个BUG,最后发现是对moveToThread()函数理解不到位导致的。为了弄清楚这个问题最好将Demo代码拷贝,跟着跑一遍。

//a.h
#pragma once
#include "c.h"class A: public QObject
{Q_OBJECT
public:A();
public:void begin();public:QThread* subThread;int x;C* c;
};
//a.cpp
#include "a.h"
#include <QThread>
#include <QDebug>
#include <QTimer>A::A():subThread(new QThread),c(new C)
{qDebug() << "1=" << QThread::currentThreadId();this->moveToThread(subThread);qDebug() << "2=" << QThread::currentThreadId();connect(subThread, &QThread::started, this, &A::begin);
}
void A::begin(){qDebug() <<"begin()" << QThread::currentThread();// QTimer* timer = new QTimer(c);}
//c.h
#pragma once
#include <QObject>
class C:public QObject{Q_OBJECT
public:C();void print();
};
//c.cpp
#include "c.h"
#include <QThread>
#include <QDebug>
C::C(){}
void C::print(){qDebug() << "C=" <<QThread::currentThreadId();
}
//main.cpp
#include "mainwindow.h"
#include "a.h"
#include <QApplication>
#include<QThread>
#include<QDebug>
int main(int argc, char *argv[])
{QApplication a(argc, argv);A* aa = new A;aa->subThread->start();return a.exec();
}

一、moveToThread()执行后,当前代码线程没有改变。

在这里插入图片描述
为了方便说明问题,这里引入线程作用域的概念,它表示哪些变量加入该线程。this->moveToThread(subThread) 的作用是将在主线程中类A的对象本身加入子线程subThread。由于moveToThread()只是在将调用者加入到其他线程的作用域里,所以当前线程没有任何变化。需要注意的是,此时A对象同时属于两个线程的作用域:主线程和子线程sunThread。

二、对象执行moveToThread()后,哪些成员加入了子线程

如果想当然的认为 this->moveToThread(subThread) 将this所指对象的全部成员加入到subThread的作用域中,那么就会大错特错。首先考虑A中方法begin(),通过调用可以发现通过信号started调用时,它的线程ID=0x321c,说明 this->moveToThread(subThread) 将对象的方法加入了子线程的作用域。

下面取消代码中的注释:
在这里插入图片描述
然后运行代码,发现程序报错:
在这里插入图片描述
这是因为Qt不允许为线程作用域外的对象创建子对象。同时这说明A的属性 c 并没有加入到子线程subThread中。解决方法有三个:

1、创建对象时不指定父对象

 QTimer* timer = new QTimer(); //这样只适用于一小部分情况

2、对属性对象使用moveToThread加入子线程作用域

c->moveToThread(subThread);	//这是一个简单有效的办法

3、将属性对象的创建放到子线程中执行

void A::begin(){qDebug() <<"begin()" << QThread::currentThreadId();c = new C;QTimer* timer = new QTimer(c);
}

三、C++内存模型

c++内存模型参考内存模型。
C++内存分为堆、栈、代码区、全局/静态存储区、常量存储区共5个区域。
结合C++内存模型,可以知道类的方法与类的属性对象存储区域不一样,也就可以解释为什么moveToThread只是将类的方法加入子线程的作用域。

相关文章:

Qt多线程之moveToThread()函数

文章目录 一、moveToThread()执行后&#xff0c;当前代码线程没有改变。二、对象执行moveToThread()后&#xff0c;哪些成员加入了子线程1、创建对象时不指定父对象2、对属性对象使用moveToThread加入子线程作用域3、将属性对象的创建放到子线程中执行 三、C内存模型 在使用“继…...

【WEB前端2024】智体OS:poplang编程控制成本小千元的长续航robot机器人底盘(开源)

【WEB前端2024】智体OS&#xff1a;poplang编程控制成本小千元的长续航robot机器人底盘&#xff08;开源&#xff09; 前言&#xff1a;dtns.network是一款主要由JavaScript编写的智体世界引擎&#xff08;内嵌了three.js编辑器的定制版-支持以第一视角游览3D场馆&#xff09;…...

动态规划法学习

当然&#xff0c;让我们用更生活化的语言和一个实际的例子来解释动态规划&#xff0c;以及如何在实践中应用它。 动态规划通俗理解 想象一下&#xff0c;你是个水果摊老板&#xff0c;每天要决定订购多少苹果&#xff0c;目标是最大化利润。但苹果的价格每天波动&#xff0c;…...

前端技术回顾系列 10|TS 泛型在类和接口中的应用

在微信中阅读,关注公众号:CodeFit。 创作不易,如果你觉得这篇文章对您有帮助,请不要忘了 点赞、分享 和 关注 我的公众号:CodeFit,为我的持续创作提供动力。 上文回顾:约束泛型(Generic Constraints) 上一篇文章我们回顾了 泛型 在 TypeScript 中的高级用法 —— 泛型…...

【Ardiuno】实验ESP32单片机自动配置Wifi功能(图文)

这里小飞鱼按照ESP32的示例代码&#xff0c;实验一下wifi的自动配置功能。所谓的自动配置&#xff0c;就是不用提前将wifi的名称和密码写到程序里&#xff0c;这样可以保证程序在烧录上传后&#xff0c;可以通过手机端的软件来进行配置&#xff0c;可以避免反复修改代码&#x…...

xml数据解析

XML Pull Parser&#xff08;使用Android的XmlPullParser&#xff09; 原理 Pull Parser允许应用程序代码从XML数据中“拉取”事件&#xff0c;而不是像SAX那样通过事件处理程序被“推送”。应用程序代码可以决定何时拉取下一个事件&#xff0c;如开始元素、结束元素或文本内…...

vite工程化搭建vue项目之自动按需导入

背景 当我们在使用vue3组合式开发的时候&#xff0c;大多数情况下我们的代码可能是这样的 <script setup lang"ts"> import { ref, reactive, toRefs, onMounted, computed } from vue; defineProps({}); </script><template><div></di…...

yolo-inference多后端+多任务+多算法+多精度模型 框架开发记录(python版)

先贴出github地址&#xff0c;欢迎大家批评指正&#xff1a;https://github.com/taifyang/yolo-inference 不知不觉LZ已经快工作两年了&#xff0c;由于之前的工作内容主要和模型部署相关&#xff0c;想着利用闲暇时间写一些推理方面的经验总结&#xff0c;于是有了这个工程。其…...

uniapp使用vue3语法构建自定义导航栏,适配小程序胶囊

具体代码 <template><view class"nav-wrapper-container" :style"height:navBarHeight px"><view class"nav-status-container" :style"height:navstatusBarHeight px;" /><view v-if"isCustom" clas…...

wpf、winform 监听USB拔插时触发

C# USB拔插监听 C#查找设备管理器中所有的 USB 设备 wpf、winform 监听USB拔插时触发 监听Windows USB 拔插时触发 private void MainWindow_Loaded(object sender, RoutedEventArgs e){FleckWebSocketConfig.OpenSocketConfig().GetAwaiter(); //websocket 服务开启用于监听W…...

C语言:指针笔试题

// 输入某一年的第几天&#xff0c;计算并输出它是这一年的第几月第几日。 /* 函数功能: 对给定的某一年的第几天&#xff0c;计算它是这一年的第几月第几日。 函数入口参数: 整形变量year,存储年&#xff1b; 整形变量yearDay,存储某一年的第几天&am…...

搜维尔科技:Movella旗下的Xsens在人形机器人开发中得到广泛应用

人形机器人的发展正在全球范围内受到广泛关注。作为机器人领域的重要分支&#xff0c;人形机器人因其具备高度仿真的外观和动作&#xff0c;以及更贴近人类的行为模式&#xff0c;有望逐渐成为人们日常生活和工业生产中的得力助手。在中国&#xff0c;这一领域的发展尤为引人注…...

k8s学习--kubernetes服务自动伸缩之水平伸缩(pod副本伸缩)HPA详细解释与案例应用

文章目录 前言HPA简介简单理解详细解释HPA 的工作原理监控系统负载模式HPA 的优势使用 HPA 的注意事项应用类型 应用环境1.metircs-server部署2.HPA演示示例&#xff08;1&#xff09;部署一个服务&#xff08;2&#xff09;创建HPA对象&#xff08;3&#xff09;执行压测 前言…...

Mock数据

Mock 数据 引入依赖 <dependency><groupId>com.github.jsonzou</groupId><artifactId>jmockdata</artifactId><version>4.3.0</version></dependency>mock 数据 MockConfig mockConfig new MockConfig().sizeRange(1, 1);A.…...

【MySQL】性能分析

https://www.bilibili.com/video/BV1Kr4y1i7ru/?p78 查看执行频次 查看当前数据库的 INSERT, UPDATE, DELETE, SELECT 访问频次&#xff1a; SHOW GLOBAL STATUS LIKE Com_______; 或者 SHOW SESSION STATUS LIKE Com_______; 慢查询日志 慢查询日志记录了所有执行时间超过指…...

MyBatis插件机制

MyBatis插件机制是该框架提供的一种灵活扩展方式&#xff0c;允许开发者在不修改框架源代码的情况下对MyBatis的功能进行定制和增强。这种机制主要通过拦截器&#xff08;Interceptor&#xff09;实现&#xff0c;使得开发者可以拦截和修改MyBatis在执行SQL语句过程中的行为。 …...

NVIDIA Jetson Linux 35.3.1-开发指南-导言

原文地址&#xff1a;Welcome — Jetson Linux Developer Guide documentation (nvidia.com) 欢迎 本开发人员指南适用于 NVIDIA Jetson Linux版本 35.3.1 GA 。 最后更新: 2023年5月19日 NVIDIA Jetson是世界领先的边缘AI平台。其高性能、低功耗计算 深度学习 &#xff0c;…...

14. fastLED调色板

Color Palettes Functions and class definitions for color palettes.调色板的函数和类定义。 RGB palettes map an 8-bit value (0-255) to an RGB color. You can create any color palette you wish; a couple of starters are provided: ForestColors_p, CloudColors_p…...

bugku---misc---赛博朋克

1、下载附件解压之后是一个txt文本&#xff0c;查看文本的时候看到头部有NG的字样 2、把txt改为png后缀得到一张图片 3、binwalk没发现奇怪的地方&#xff0c;分离出来还是图片 4、stegslove分析&#xff0c;切换图片没有发现奇怪地方 5、将通道rgb置为0。出现了flag但是flag不…...

vue+elementplus模拟“山野愚人居”简单实现个人博客

目录 一、项目介绍 二、项目截图 1.项目结构图 2.项目首页 3.文章详情 4.留言 5.读者 三、源码实现 1.项目依赖package.json 2.项目启动 3.读者页面源码 四、总结 一、项目介绍 模仿原博客&#xff1a;山野愚人居 - 记录我的生活、所见、所闻、所想…… 本项目参考以…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...