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

解决Qt多线程中fromRawData函数生成的QByteArray数据不一致问题

解决Qt多线程中fromRawData函数生成的QByteArray数据不一致问题

icon

目录

    • 🔔 问题背景
    • 📄 问题代码
    • ❓ 问题描述
    • 🩺 问题分析
    • ✔ 解决方案


🔔 问题背景

在开发一个使用Qt框架的多线程应用程序时,我们遇到了一个棘手的问题:在不同线程中打印同一个QByteArray对象的内容时,得到了不一致的结果。这个问题出现在一个设备通信类中,该类使用一个工作线程来读取设备数据,然后通过信号-槽机制将数据传递到主线程进行处理。



📄 问题代码

代码结构如下:

class DeviceManager : public QObject {
public:DeviceManager() : QObject() {m_worker = new Worker();m_workerThread = new QThread(this);m_worker->moveToThread(m_workerThread);connect(m_workerThread, &QThread::started, m_worker, &Worker::readDevice);connect(m_worker, &Worker::dataReady, this, &DeviceManager::processData);m_workerThread->start();}~DeviceManager() {m_hidWork->breakFlag = false;m_hidWorkThread->quit();m_hidWorkThread->wait();m_hidWorkThread->deleteLater();}private:void processData(QByteArray data) {qDebug() << "Main thread: " << data.toHex(' ');}class Worker;Worker *m_worker;QThread *m_workerThread;
};class DeviceManager::Worker : public QObject {Q_OBJECT
public:Worker(QObject *parent = nullptr) : QObject(parent) {}bool breakFlag = true;void readDevice() {auto buffer = new char[1024];while(breakFlag) {size_t size = 5;memset(buffer, 0, size)// 这里是模拟读取设备数据buffer = {0x01, 0x02, 0x03, 0x04, 0x05};QByteArray deviceData = QByteArray::fromRawData(reinterpret_cast<char*>(buffer), size);qDebug() << "Worker thread: " << deviceData.toHex(' ');emit dataReady(QByteArray(deviceData));}}signals:void dataReady(QByteArray data);
};


❓ 问题描述

在运行这段代码时,当主线程进行了一个UI阻塞操作的时候,我们观察会到工作线程和主线程中打印的QByteArray内容不一致。例如:

Worker thread: 01 02 03 04 05
Main thread: 00 00 00 00 00

这显然不是我们期望的结果,因为两个线程应该打印相同的数据。



🩺 问题分析

经过仔细分析,我们发现问题的根源在于QByteArray::fromRawData()的使用方式。这个函数创建了一个共享底层数据QByteArray,而不是复制数据。这意味着:

  • fromRawData()创建的QByteArray与原始缓冲区共享数据
  • 当原始缓冲区被修改或释放时,QByteArray的内容可能变得无效
  • 在跨线程传递时,如果原始数据发生变化,接收线程可能会得到意外的结果


✔ 解决方案

解决这个问题的关键是确保在发送信号时创建QByteArray完整副本。以下是修改后的Worker::readDevice()方法:

void Worker::readDevice() {auto buffer = new char[1024];while(breakFlag) {size_t size = 5;memset(buffer, 0, size)// 这里是模拟读取设备数据buffer = {0x01, 0x02, 0x03, 0x04, 0x05};//QByteArray deviceData = QByteArray::fromRawData(reinterpret_cast<char*>(buffer), size);QByteArray deviceData((reinterpret_cast<char*>(buffer), size);  // 创建数据的副本qDebug() << "Worker thread: " << deviceData.toHex(' ');emit dataReady(deviceData);}	    
}

这里的改动看似很小,但却解决了问题:

  • 我们使用QByteArray(const char *data, int size)构造函数来创建QByteArray
  • 这个构造函数会复制提供的数据,而不是共享它。
  • 结果是一个独立的QByteArray对象,其内容不会受到原始缓冲区变化的影响。


相关文章:

解决Qt多线程中fromRawData函数生成的QByteArray数据不一致问题

解决Qt多线程中fromRawData函数生成的QByteArray数据不一致问题 目录 &#x1f514; 问题背景&#x1f4c4; 问题代码❓ 问题描述&#x1fa7a; 问题分析✔ 解决方案 &#x1f514; 问题背景 在开发一个使用Qt框架的多线程应用程序时&#xff0c;我们遇到了一个棘手的问题&…...

datax关于postsql数据增量迁移的问题

看官方文档是不支持的 数据源及同步方案_大数据开发治理平台 DataWorks(DataWorks)-阿里云帮助中心 (aliyun.com) 看了下源码有个postsqlwriter 看了下也就拼接sql 将 PostgresqlWriter中的不允许更新先注释了 让他过去先 然后看到 WriterUtil中的对应方法 getWriteTemplat…...

【Go】实现字符切片零拷贝开销转为字符串

package mainimport ("fmt""unsafe" )func main() {bytes : []byte("hello world")s : *(*string)(unsafe.Pointer(&bytes))fmt.Println(s)bytes[0] Hfmt.Println(s) }slice的底层结构是底层数组、len字段、cap字段。string的底层结构是底层…...

[sqlserver][sql]sqlserver查询执行过的历史sql

SQL是一个针对SQL Server数据库的查询执行过的历史 select * from (SELECT *FROM sys.dm_exec_query_stats QS CROSS APPLY sys.dm_exec_sql_text(QS.sql_handle) ST ) a where a.creation_time >2018-07-18 17:00:00 and charindex(delete from ckcdlist ,text)>0 an…...

python中n次方怎么表示

Python中的n次方用pow()方法来表示&#xff0c;pow()方法返回 xy&#xff08;x的y次方&#xff09;的值。 语法 以下是 math 模块 pow() 方法的语法&#xff1a; import math math.pow( x, y ) 内置的 pow() 方法 pow(x, y[, z]) 函数是计算x的y次方&#xff0c;如果z在存在&…...

Java数组怎么转List,Stream的基本方法使用教程

Stream流 Java 的 Stream 流操作是一种简洁而强大的处理集合数据的方式,允许对数据进行高效的操作,如过滤、映射、排序和聚合。Stream API 于 Java 8 引入,极大地简化了对集合(如 List、Set)等数据的处理。 一、创建 Stream 从集合创建: List<String> list = Ar…...

2024-07-12 - 基于 sealos 部署高可用 K8S 管理系统

摘要 Sealos 是一款以 Kubernetes 为内核的云操作系统发行版。它以云原生的方式&#xff0c;抛弃了传统的云计算架构&#xff0c;转向以 Kubernetes 为云内核的新架构&#xff0c;使企业能够像使用个人电脑一样简单地使用云。 操作实践 1、服务器规划 kubernetes集群大体上…...

Ps:首选项 - 单位与标尺

Ps菜单&#xff1a;编辑/首选项 Edit/Preferences 快捷键&#xff1a;Ctrl K Photoshop 首选项中的“单位与标尺” Units & Rulers选项卡允许用户根据工作需求定制 Photoshop 的测量单位和标尺显示方式。这对于保持工作的一致性和精确性&#xff0c;尤其是在跨设备或跨平台…...

DiskDigger(文件恢复工具) v2.0.3 中文授权版

DiskDigger中文版是一款实用文件恢复工具&#xff0c;它能从任何媒介中恢复误删除的文件。支持硬盘、USB 闪存盘、闪存卡(SD/CF/MMS)、CD、DVD 和软盘等。支持恢复任何格式的文件。DiskDigger 能彻底的扫描每个扇区来跟踪文件&#xff0c;从而最大限度恢复挽回文件信息。 软件…...

C/C++逆向:x96dbg(x64dbg/x86dbg)的使用

这篇文章主要来说一下x96dbg(x64/x86)的基本使用&#xff0c;这里还是使用上篇文章中的简单程序用来作为本篇文章的实例&#xff0c;因为上篇文章再生成程序时选用的解决方案平台为x86所以生成的程序则需要我们使用x32dbg来进行分析。 这边与IDA一样&#xff0c;我们可以将程序…...

超声波清洗机是智商税吗?专业博主分享四大必买超声波清洗机款式

有些人觉得超声波清洗机不过是个“智商税”&#xff0c;花几百块买个小盒子不值当&#xff0c;毕竟自己用手也能清洗。但这种看法过于片面。事实上&#xff0c;超声波清洗已经有几十年的历史&#xff0c;随着科技的发展&#xff0c;现代超声波清洗机不仅能够批量、自动清洁&…...

TIM输出比较

文章目录 前言一、TIM输出比较简介二、PWM简介2.1 PWM基本概念2.2 PWM参数2.3 PWM波形2.4 PWM基本结构2.5 PWM参数计算 三、舵机简介3.1 舵机的工作原理3.2 输入PWM信号的要求3.3 硬件电路 四、直流电机及驱动简介4.1 直流电机4.2 TB6612电机驱动芯片 前言 提示&#xff1a;本…...

JNPF 5.0升级钜惠,感恩回馈永远在路上

尊敬的JNPF用户们&#xff1a; 经过引迈团队数月的辛勤努力和不断的技术创新&#xff0c;JNPF快速开发平台迎来全新升级——5.0版本&#xff01;此次5.0版本的迭代革新&#xff0c;不仅代表着我们技术实力的进一步提升&#xff0c;是我们对用户需求的深度理解和积极回应。为了…...

三维平面电磁铁、交流电磁铁、显微镜磁场北京大学方案

根据用户北京大学需求设计制造方案如下 三维平面电磁铁产品规格 5MPS63-25型三维平面电磁铁&#xff0c;X、Y方向磁场由2对正交的磁极产生&#xff0c;Z轴由一组同轴线圈产生&#xff1b; 每轴对应的两个线圈正接产生均匀磁场&#xff0c;反接产生梯度磁场&#xff1b; …...

awk引号转义问题

这是我在终端运行的脚本&#xff1a; for ib1 in $(seq 0 999);do ibstr$(printf sample52-%d $ib1);calculate_rmsd --reorder Motif52.pdb ${ibstr}.pdb | awk "{printf "%d %8f\n", $ib1, $0}" >> sample52_hotspots; done 但是报错&#xff1a; …...

C语言典型例题46

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 题目&#xff1a; 习题3.6 企业发放的奖金根据利润提成。利润I低于或等于100 000元的&#xff0c;奖金可提成10%&#xff1b; 利润高于100 000元&#xff0c;低于200000元&…...

【目标检测】AGMF-Net:遥感目标检测的无注意力全局多尺度融合网络

《Attention-Free Global Multiscale Fusion Network for Remote Sensing Object Detection》 遥感目标检测的无注意力全局多尺度融合网络 原文&#xff1a;https://ieeexplore.ieee.org/document/10371366 摘要 遥感目标检测&#xff08;RSOD&#xff09;在复杂背景和小目标…...

2007-2022年上市公司资源节约数据

2007-2022年上市公司资源节约数据 1、时间&#xff1a;2007-2022年 2、来源&#xff1a;上市公司年报、社会责任报告、上市公司网站信息 3、指标&#xff1a;水资源节约、电力节约、原煤节约、天然气节约、汽油节约、柴油节约、集中供热节约、折算成统一标准煤共计节约 4、…...

onlyoffice连接器(connector)开发使用精讲 二次开发 深入开发【一】

连接器是onlyoffice调用web api的一个基础工具&#xff0c;可以方便开发者或者用户与业务系统结合使用web功能。 关于connector官方说明文档在这里&#xff1a;Automation API - ONLYOFFICE Api Documentation 注意&#xff1a;该功能针对开发者版、企业版&#xff0c;社区版常…...

VAuditDemo安装漏洞

目录 VAuditDemo安装漏洞 index.php header.php config.php lib.php install.php 分析结果 漏洞利用 第一步&#xff1a;删除install.lock文件&#xff0c;访问 install.php 抓包 第二步&#xff1a;通过审计构造payload 第三步&#xff1a;修改抓包请求内容&#x…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

云安全与网络安全:核心区别与协同作用解析

在数字化转型的浪潮中&#xff0c;云安全与网络安全作为信息安全的两大支柱&#xff0c;常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异&#xff0c;并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全&#xff1a;聚焦于保…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

&#x1f9e0; LangChain 中 TextSplitter 的使用详解&#xff1a;从基础到进阶&#xff08;附代码&#xff09; 一、前言 在处理大规模文本数据时&#xff0c;特别是在构建知识库或进行大模型训练与推理时&#xff0c;文本切分&#xff08;Text Splitting&#xff09; 是一个…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…...

深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙

WebGL&#xff1a;在浏览器中解锁3D世界的魔法钥匙 引言&#xff1a;网页的边界正在消失 在数字化浪潮的推动下&#xff0c;网页早已不再是静态信息的展示窗口。如今&#xff0c;我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室&#xff0c;甚至沉浸式的V…...

数据库正常,但后端收不到数据原因及解决

从代码和日志来看&#xff0c;后端SQL查询确实返回了数据&#xff0c;但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离&#xff0c;并且ai辅助开发的时候&#xff0c;很容易出现前后端变量名不一致情况&#xff0c;还不报错&#xff0c;只是单…...