解决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对象,其内容不会受到原始缓冲区变化的影响。


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

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

相关文章

使用 LangGraph 构建工作流, 实现与虚拟女友对话

文章目录 简介背景流程图代码实现 简介 介绍了如何使用 LangGraph 搭建一个基于聊天机器人的工作流&#xff0c;具体实现了一个虚拟女友的角色扮演游戏。 通过流程图展示了构建完成的状态图&#xff0c;并介绍了各个节点的功能&#xff0c;如接收用户输入、生成对话等。提供了…

如何使用ssm实现保险业务管理系统设计与实现

TOC ssm131保险业务管理系统设计与实现jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规…

ArcGIS Pro基础:设置2个窗口同步联动界面

如上所示&#xff0c;通过1步骤&#xff0c;新建了2个地图窗口&#xff0c;得到2和3所表示的【地图1】、【地图2】&#xff0c;一个是影像图&#xff0c;另一个是地形图&#xff0c; 假如有个需求&#xff0c;是将2个窗口联动起来&#xff1a;在观察影像的同时&#xff0c;也同…

[000-01-022].第06节:RabbitMQ中的交换机介绍

1.什么是Exchanges(交换机&#xff09;: 1.RabbitMQ 消息传递模型的核心思想是: 生产者生产的消息从不会直接发送到队列。实际上&#xff0c;通常生产者甚至都不知道这些消息传递传递到了哪些队列中2.生产者只能将消息发送到交换机(exchange)&#xff0c;交换机工作的内容非常…

Android Room DataBase

Room数据库是在Sqlite的基础上&#xff0c;进行了封装和优化。这让我们可以摆脱&#xff0c;繁琐的数据库操作 在module的gradle里面&#xff0c;加入: dependencies {annotationProcessor "androidx.room:room-compiler:2.3.0"implementation androidx.room:room-…

调用股票网站接口读取大A数据——个股资金流入趋势

以某股票为例&#xff0c;调用自定义的一个类&#xff0c;读取数据。 class BigAData:# 获取资金流向数据def get_money_flow(self, stock_code, page1, num20, sortopendate, asc0):该函数通过股票代码从新浪财经API获取资金流向数据。参数包括股票代码、页数、每页数量、排序…

jenkins最佳实践(一):jenkins安装与部署

各位小伙伴们大家好呀&#xff0c;我是小金&#xff0c;下面我将记录学习jenkins的系列文章与心得&#xff0c;一方面用于博主的自我记录&#xff0c;一方面如果能帮助到正在浏览这篇文章的小伙伴&#xff0c;那更好不过了&#xff0c;本篇文章主要讲述jenkins的安装以及安装je…

Redis篇一:初识Redis

文章目录 前言1. 初始Redis2. MySQL VS Redis3. 什么是分布式系统&#xff08;也是一种处理大量数据时的处理方式&#xff09;3.1 单机架构3.2 数据库与应用服务分离3.3 负载均衡3.4 数据库读写分离3.5 引入缓存&#xff08;Redis&#xff09;3.6 数据库分库分表3.7 引入微服务…

计算机毕业设计选题推荐-OA办公管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

白酒与青年文化:潮流与传统的碰撞

在时代的洪流中&#xff0c;青年文化如同一股涌动的潮流&#xff0c;不断冲击着传统的边界。而白酒&#xff0c;作为中国传统文化的瑰宝&#xff0c;也在这一潮流中找到了新的表达方式。今天&#xff0c;我们就来探讨一下白酒与青年文化之间的碰撞与整合&#xff0c;以及豪迈白…

【Vue3】编程式路由导航

【Vue3】编程式路由导航 背景简介开发环境开发步骤及源码总结 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日…

微服务事务管理

1.分布式事务问题 1.1.本地事务 本地事务&#xff0c;也就是传统的单机事务&#xff0c;在传统数据库事务中&#xff0c;必须要满⾜四个原则&#xff1a; 1.2.分布式事务 分布式事务&#xff0c;就是指不是在单个服务或单个数据库架构下&#xff0c;产⽣的事务&#xff0c;例…

全感知、全覆盖、全智能的名厨亮灶开源了

简介 AI视频监控平台, 是一款功能强大且简单易用的实时算法视频监控系统。愿景在最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;减少企业级应用约 95%的开发成本&#xff0c;在强大视频算法加…

数学基础(七)

一、熵 熵代表物体内部的混乱程度。&#xff08;一件事发生的不确定性&#xff09; 熵应用到分类任务中 二、激活函数 Sigmoid函数&#xff1a; Tanh函数&#xff1a; Relu函数&#xff1a; 三、回归分析 回归分析是寻找存在相关关系的变量间的数学表达式&#xff0c;并进行…

[数据集][目标检测]电力场景输电线异物检测数据集VOC+YOLO格式2060张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2060 标注数量(xml文件个数)&#xff1a;2060 标注数量(txt文件个数)&#xff1a;2060 标注…

Spring Data JPA 中分页Pageable 的使用说明

我 | 在这里 ⭐ 全栈开发攻城狮、全网10W粉丝、2022博客之星后端领域Top1、专家博主。 &#x1f393;擅长 指导毕设 | 论文指导 | 系统开发 | 毕业答辩 | 系统讲解等。已指导60位同学顺利毕业 ✈️个人公众号&#xff1a;热爱技术的小郑。回复 Java全套视频教程 或 前端全套视频…

黑神话悟空什么配置可以玩?什么样的游戏本配置可以畅玩《黑神话:悟空》?黑神话悟空电脑配置推荐

相信不少游戏爱好者&#xff0c;近期被《黑神话&#xff1a;悟空》这款游戏刷屏了&#xff0c;预售开启不到5分钟&#xff0c;所有的产品即宣告售罄&#xff0c;预购3天销售额就破亿&#xff0c;并迅速登顶Steam全球榜。作为一款备受期待的国产3A游戏&#xff0c;以其精美的画面…

致远OA OCR票据识别组件

OCR票据识别 技术支持 技术大佬支持本文档 使用范围 任何票种信息&#xff0c;只要需要对接到oa底表中&#xff0c;就能够实现各种票种&#xff0c;各种字段的对接&#xff0c;包括票据识别&#xff0c;发票核验&#xff0c;适配各种票据 使用介绍 1 配置每种发票的ocr设…

【html+css 绚丽Loading】000016 四维玄方

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…

《牛虻》读后感

《牛虻》这本书是同事送的&#xff0c;最近换工作、搬家很多杂事&#xff0c;也就没有多少看书的兴致&#xff0c;所以断断续续看了快两周才看完。这是爱尔兰女作家埃塞尔丽莲伏尼契的代表作&#xff0c;在我国声名远播&#xff0c;是一代人的精神食粮。怀着崇敬的心情翻开这本…