Qt ---进程间的通信

进程间通讯方式
Qt 提供了四种进程间通信的方式:

使用共享内存(shared memory)交互:这是Qt 提供的一种各个平台均有支持的进程间交互的方式。
TCP/IP:其基本思想就是将同一机器上面的两个进程一个当做服务器,一个当做客户端,二者通过网络协议进行交互。除了两个进程是在同一台机器上,这种交互方式与普通的C/S 程序没有本质区别。Qt 提供了QNetworkAccessManager 对此进行支持。
D-Bus:freedesktop 组织开发的一种低开销、低延迟的IPC 实现。Qt 提供了QtDBus模块,把信号槽机制扩展到进程级别(因此我们前面强调是“普通的”信号槽机制无法实现IPC),使得开发者可以在一个进程中发出信号,由其它进程的槽函数响应信号。
QCOP(Qt COmmunication Protocol):QCOP 是Qt 内部的一种通信协议,用于不同的客户端之间在同一地址空间内部或者不同的进程之间的通信。目前,这种机制只用于Qt for Embedded Linux 版本。进程之间通讯方式种类繁多,在Qt 下,一般使用TCP/IP 比较简单和方便。

使用原因
  就难易程度,使用习惯及速度方面,进程间通讯,TCP无疑是很好的。
  某次一个相机项目中,需要同时打开使用n个相机,单个进程实现需要对相机提供的SDK 进行很大的改动,所以采用了进程间通讯的方式来完成任务。
  首先采用了TCP通讯,所有收发命令都做好后,进行测试,当开启相机实时预览的时候,TCP出现了“假死”,即这边发送消息,另一边怎么都没反应,使用wireshark ,抓包发现,一旦发送了实时预览命令开启预览后,后面无论发送什么消息。wireshark 都没有数据包,并且最终信息提示 TCP 出现了问题(图片信息及出现的问题错误代码,现在没有了,期间电脑固态坏了,数据没了),这个错误问题,经搜索引擎最终没能解决(这个问题还是没有探索出来)。
  问题没能解决,只能更换方案。
原文链接:https://blog.csdn.net/dxa572862121/article/details/104994436

共享内存(Shared Memory)是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。共享内存实际就是内存映射的一种特殊情况。在《windows核心编程》写道:

在Windows中,在同一台机器上数据共享的最底层机制就是内存映射文件。 这种数据共享机制是通过让两个或多个进程映射同一个文件映射对象的视图来实现,意味着在进程间共享相同的物理存储页面。对多个进程共享同一个文件映射对象来说,所有进程使用的文件映射对象的名称必须完全相同。

共享内存的方式原理就是将一份物理内存映射到不同进程各自的虚拟地址空间上,其它进程打开该文件映射对象就可以访问该内存块,这样每个进程都可以读取同一份数据,从而实现进程通信。因为是通过内存操作实现通信,因此是一种最高效的数据交换方法。由于共享内存是用文件映射实现的,所以它也有较好的安全性,也只能运行于同一计算机上的进程之间。

Qt提供了QSharedMemory类和QSystemSemaphore类,QSharedMemory可以访问共享内存区域,以及多线程和进程的共享内存区域。而QSystemSemaphore类用于访问系统共享资源,以实现独立进程间的通信。

原文链接:https://blog.csdn.net/Sakuya__/article/details/89519412

(一)向共享内存中提供数据的一方:

  1,定义QSharedMemory shareMemory,并设置标志名shareMemory.setKey(),例如shareMemory.setKey("shareimg");

  2,将共享内存与主进程分离 shareMemory.detach();

  3,创建共享内存 shareMemory.create();

  4,将共享内存上锁shareMemory.lock();

  5,将进程中要共享的数据拷贝到共享内存中;

  6,将共享内存解锁shareMemory.unlock();

新建项目1,代码:

write.h

#ifndef WRITE_H
#define WRITE_H
#include <QWidget>
#include <QSharedMemory>
QT_BEGIN_NAMESPACE
namespace Ui { class write; }
QT_END_NAMESPACEclass write : public QWidget
{Q_OBJECTpublic:write(QWidget *parent = nullptr);~write();private slots:void on_pushButton_clicked();private:Ui::write *ui;QSharedMemory sharedmomory;
};
#endif // WRITE_H

 write.cpp

#include "write.h"
#include "ui_write.h"
#include<QDebug>
write::write(QWidget *parent): QWidget(parent), ui(new Ui::write)
{ui->setupUi(this);sharedmomory.setKey("My_Shared_Memory");//
}write::~write()
{delete ui;
}void write::on_pushButton_clicked()
{if(sharedmomory.isAttached())//如果共享内存被绑定,则解除绑定{sharedmomory.detach();}if(!sharedmomory.create(100,QSharedMemory::ReadWrite))  //bool create(int size, AccessMode mode = ReadWrite);{qDebug()<<"failed to create shared momory";return;}sharedmomory.lock(); //共享内存上锁QByteArray arr=ui->lineEdit->text().toLatin1();//文本转换成QByteArray类型//void * __cdecl memcpy(void * __restrict__ _Dst,const void * __restrict__ _Src,size_t _Size)//参数一  拷贝到哪里去  是个地址,参数二  参数的来源 是个地址,参数三   拷贝的大小memcpy(sharedmomory.data(),arr.data(),(size_t)qMin(sharedmomory.size(),ui->lineEdit->text().size()));//共享内存的大小与你输入的大小作比较,取出较小的那个sharedmomory.unlock(); //共享内存锁
}

ui设计器添加控件如图:

(二)从共享内存中取数据的一方:

  1,定义QSharedMemory shareMemory,并设置共享内存的标志名shareMemory.setKey()注意设置的要与提供内存共享的一方要一样,本例是shareMemory.setKey("shareimg")。

  2,将共享内存上锁shareMemory.lock();

  3,将共享内存与主进程绑定shareMemory.attach(),使该进程可以访问共享内存的数据;

  4,从共享内存中取数据;

  5,使用完后将共享内存解锁shareMemory.unlock(),最后将共享内存与该进程分离shareMemory.detach();

新建项目2,代码:

read.h

#ifndef READ_H
#define READ_H
#include <QWidget>
#include <QSharedMemory>
QT_BEGIN_NAMESPACE
namespace Ui { class read; }
QT_END_NAMESPACEclass read : public QWidget
{Q_OBJECTpublic:read(QWidget *parent = nullptr);~read();private slots:void on_pushButton_clicked();private:Ui::read *ui;QSharedMemory sharedmomory;
};
#endif // READ_H

read.cpp

#include "read.h"
#include "ui_read.h"
#include<QDebug>
read::read(QWidget *parent): QWidget(parent), ui(new Ui::read)
{ui->setupUi(this);sharedmomory.setKey("My_Shared_Memory");
}read::~read()
{delete ui;
}void read::on_pushButton_clicked()
{if(!sharedmomory.attach()){qDebug()<<"Attach shared momory failed";return;}sharedmomory.lock();char *arr=new char[sharedmomory.size()]; //开辟出与共享资源同样大小的空间memcpy(arr,sharedmomory.data(),(size_t)sharedmomory.size());//将write共享内存sharedmomory开辟出来的内容 拷贝到arr开辟出来的内存空间中ui->label->setText(QString(arr));//将arr的内容转换为QString类型显示sharedmomory.unlock();sharedmomory.detach(); //解除绑定}

ui设计器添加控件如图:

当从write端向共享内存写入字符串后,在read端就可以独处相应的数据啦

如图:

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

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

相关文章

ChatGPT Code Interpreter实用教程,14种方法助你数据分析绘图

目录 1. 设置解释一下上传的文档高难度&#xff1a;根据文档创建10个可视化图表代表不同的数据。 1. 设置 勾选 Advanced data analysis 选择GPT-4&#xff0c;下面已经出现了代码解释器 点击 解释一下上传的文档 Prompt&#xff1a;请用简单的语言&#xff0c;解释一下该…

Redis Cluster集群运维与核心原理剖析

Redis集群方案比较 哨兵模式 在redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态&#xff0c;如果master节点异常&#xff0c;则会做主从切换&#xff0c;将某一台slave作为master&#xff0c;哨兵的配置略微复杂&#xff0c;并且性能和高可用性…

1462. 课程表 IV

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;Floyd传递闭包方法二&#xff1a;拓扑排序 思考写在最后 Tag 【拓扑排序】【传递闭包】【并查集】【数组】 题目来源 1462. 课程表 IV 题目解读 给你一个表示课程先决条件的数组 prerequisites&#xff0c;prerequis…

Unity之Android项目的打包

一 Unity里面配置Android运行环境 1.1 首先unity需要集成android编译环境&#xff0c;点击FIle->Build Settings 1.2 没是否有Android模块&#xff0c;没的话先下载Android模块 1.3 按下面的操作&#xff0c;下载Android支持&#xff0c;SDK&#xff0c;NDK&#xff0c;和J…

分布式事务解决方案之2PC

分布式事务解决方案之2PC 前面已经学习了分布式事务的基础理论&#xff0c;以理论为基础&#xff0c;针对不同的分布式场景业界常见的解决方案有2PC、 TCC、可靠消息最终一致性、最大努力通知这几种。 什么是2PC 2PC即两阶段提交协议&#xff0c;是将整个事务流程分为两个阶段…

变压器寿命预测(python代码,Logistic Regression模型预测效果一般,可以做对比实验)

1.数据来源官网&#xff1a;Data for: Root cause analysis improved with machine learning for failure analysis in power transformers - Mendeley Data 点Download All 10kb即可下载数据 2.下载下来后是这样 每一列的介绍&#xff1a; Hydrogen 氢气&#xff1b; Oxyge…

C语言之const

C语言之const const修饰全局变量 此时全局变量只能使用但是不能修改&#xff0c; 如果直接拿全局变量修改值&#xff0c;编译直接报错 如果使用全局变量的地址修改值&#xff0c;运行时程序异常结束 const修饰普通局部变量 可以读取变量的值 不能直接通过变量进行修改值&a…

[交互]交互的实战问题1

[交互]交互的实战问题1 状态码 431 Request Header Fields Too LargeReferrer Policy: no-referrer-when-downgrade路径参数高并发问题使用场景使用的方法异常情况 状态码 431 Request Header Fields Too Large 最近做项目&#xff0c;遇到一个问题&#xff0c;后台导出表格时…

GeoSOS-FLUS未来土地利用变化情景模拟模型

软件简介 适用场景 GeoSOS-FLUS软件能较好的应用于土地利用变化模拟与未来土地利用情景 的预测和分析中&#xff0c;是进行地理空间模拟、参与空间优化、辅助决策制定的有效工 具。FLUS 模型可直接用于&#xff1a; 城市发展模拟及城市增长边界划定&#xff1b;城市内 部高分…

Java基础篇

目录 1、Java语言有哪些特点 2、面向对象和面向过程的区别 3、八种基本数据类型的大小 4、标识符命名规则 5、Java 关键字 6、访问控制 7、instanceof 关键字的作用 8、final 关键字的作用 9、static 关键字作用 10、transient 关键字的作用 11、try catch final…

Virtualbox中Ubuntu根目录空间不足

现象 Virtualbox中Ubuntu根目录空间不足 解决 动态存储 虚拟机关闭先在虚拟介质管理里把硬盘Size调大开启Ubuntu用Disks或者GParted重新调整分区大小重新启动 步骤参考: https://zhuanlan.zhihu.com/p/319431032 https://blog.csdn.net/ningmengzhihe/article/details/1272…

数据结构与算法:树

目录 树 定义 结构 二叉树 定义 结构 形式 满二叉树 完全二叉树 存储 链式存储结构 数组 孩子节点 父节点 应用 查找 维持相对顺序 遍历 深度优先遍历 前序遍历 中序遍历 后序遍历 广度优先遍历 层序遍历 二叉堆 定义 自我调整 操作 插入加点 删…