Qt ---进程间的通信

news2024/11/26 5:54:39

进程间通讯方式
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_NAMESPACE

class write : public QWidget
{
    Q_OBJECT

public:
    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_NAMESPACE

class read : public QWidget
{
    Q_OBJECT

public:
    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.coloradmin.cn/o/1009287.html

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

相关文章

24考研王道408数据结构-第三章“栈、队列、数组”课后算法题(P70--栈的模拟)

第三题 #include<iostream> using namespace std;bool solution(char s[]){int n8;int numI0;for(int i0;i<n;i){if(s[i]I){numI;}if(s[i]O){if(numI0){return false;}numI--;}}return true; }int main(){//char s[8]{I,O,I,I,O,I,O,O};char s[8]{I,O,O,I,O,I,I,O};if…

电压放大器的应用范围有哪些

电压放大器是一种常见的电子设备&#xff0c;用于将输入信号的电压放大到更高的水平。它在各个领域中具有广泛的应用范围。本文将详细介绍电压放大器的应用。 音频放大器&#xff1a; 电压放大器在音频系统中起着重要作用&#xff0c;用于将来自音源&#xff08;如CD播放器、MP…

Mybatis 动态语言 - mybatis-thymeleaf

前面我们介绍了Mybatis动态SQL的使用&#xff1b;本篇我们介绍使用mybatis-thymeleaf动态语言生成动态SQL。 如果您对Mybatis动态SQL不太了解&#xff0c;建议您先进行了解后再阅读本篇&#xff0c;可以参考&#xff1a; Mybatis 动态SQL – 使用if,where标签动态生成条件语句…

为什么有人会先考二建再考一建?

因为时间&#xff0c;因为难度&#xff0c;因为需求。 首先说时间&#xff0c;考二建比考一建的限制少很多&#xff0c;很多人入职没多久&#xff0c;研究生甚至在大学就能考了。本着早考早有证&#xff0c;早考早赚钱的原则&#xff0c;很多人会选择先考二建。 再说难度&…

Jmeter —— 常用的几种断言方法(基本用法)

在使用JMeter进行性能测试或者接口自动化测试工作中&#xff0c;经常会用到的一个功能&#xff0c;就是断言&#xff0c;断言相当于检查点&#xff0c;它是用来判断系统返回的响应结果是否正确&#xff0c;以此帮我们判断测试是否通过&#xff0c;本文 主要介绍几种常用的断言&…

【Spring使用三级缓存解决循环依赖的过程】

testService1和testService2相互依赖 当Spring创建testService1对象时&#xff0c;它会先从一级缓存中查找是否存在testService1的实例。如果缓存中不存在testService1实例&#xff0c;它将继续查找二级缓存中是否存在testService1。如果二级缓存中也不存在testService1实例&…

GDAL+Java实现获取对应栅格影像经纬度对应的像素值

从前面的GDAL系列博文中&#xff0c;可以指导GDAL可以将栅格影像文件读出为对应的多维数组&#xff0c;可以读出每一个像素格对应的像素值。但如何根据经纬度直接读取像素值呢&#xff1f;博主从查阅了网上的相关文档&#xff0c;发现有个人写的计算公式是错误的&#xff0c;用…

日期类完善

目录 日期类&#xff1a; 运算符重载&#xff1a; ​编辑 赋值重载&#xff1a; 拷贝构造和赋值重载的区别&#xff1a; 实现赋值重载&#xff1a; 划分成员函数&#xff1a; 日期类的声明和定义分离 日期类-&#xff1a; 日期类- 前置后置 日期类&#xff1a; 写一个简…

获取一个对象的直接接口和间接接口

package com.ljr;import java.util.*;public class InterfaceUtils {public static List<Class<?>> getInterfaces(Object obj) {List<Class<?>> interfaces new ArrayList<>();Class<?> clazz obj.getClass();while (clazz ! null) …

(09_13)杭州站|阿里云 Serverless 技术实践营(Serverless + 大数据)开启报名!

活动简介 “Serverless 技术实战与创新沙龙 ” 是一场以 Serverless 为主题的开发者活动&#xff0c;通过一个下午的时间增进对 Serverless 技术的理解&#xff0c;快速上手,活动受众以关注 Serverless 技术的开发者、企业决策人、云原生领域创业者为主&#xff0c;活动形式为…

肖sir__mysql之子查询语句__006

一、子查询 定义:一个查询嵌套另一个查询 例如&#xff1a; 题目&#xff1a;财务部门的收入总和&#xff1b; dept&#xff1a;财务部门 incoming&#xff1a;工资 &#xff08;1&#xff09;先将一个结果查询出来&#xff1a;财务部门的编号查询出来 select dept1 from dept …

管理类联考——数学——汇总篇——知识点突破——代数——等差数列

⛲️ 一、考点讲解 1.定义 如果在数列{ a n a_n an​}中&#xff0c; a n 1 − a n d a_{n1}-a_nd an1​−an​d&#xff08;常数&#xff09; &#xff08; n ∈ N &#xff0b; &#xff09; &#xff08;n∈N_&#xff0b;&#xff09; &#xff08;n∈N&#xff0b;​&a…

一文详解融资融券操作方法和交易规则!

融资融券是投资者利用券商提供的资金或证券进行交易的一种加杠杆的金融操作方式。通过融资融券&#xff0c;投资者可以利用杠杆效应扩大自己的投资规模&#xff0c;提高投资回报。现在有很多投资者使用融资融券账户加杠杆操作&#xff0c;但很多朋友开通了融资融券却也不太会操…

《计算机视觉中的多视图几何》笔记(3)

3 Projective Geometry and Transformations of 3D 这章主要讲的是3D的射影几何&#xff0c;与2D的射影几何差不多。主要区别是&#xff1a; 3D射影几何对偶的是点和平面&#xff0c;直线是自对偶的。3D空间中直线有4个自由度&#xff0c;这一现象并不是那么容易直接得出。一…

DHCP与静态IP:哪种适合你的网络需求?

​如今&#xff0c;大多数网络设备&#xff08;如路由器或网络交换机&#xff09;都使用IP协议作为通过网络进行通信的标准。在IP协议中&#xff0c;网络上的每个设备都有一个唯一的标识符&#xff0c;称为IP地址。实现这一点的最简单方法是配置固定IP地址或静态IP地址。由于静…

Hyperopt:分布式异步超参数优化(Distributed Asynchronous Hyperparameter Optimization)

1、概述 在深度学习的训练模型过程中&#xff0c;参数的优化是一个比较繁琐的过程&#xff0c;一般使用网格搜索Grid search与人工搜索Manual search&#xff0c;所以这个参数优化有时候看起来就像太上老君炼丹&#xff0c;是一个有点玄的东西。 那有没有一种可以自动去调优的…

c\c++ windows自动打开cmd并进入mysql

每次不用可视化工具查看数据库的时候饭都要winr->cmd->mysql -u root -p->密码 虽然不麻烦但是多少也得消耗你几秒钟&#xff0c;秉承着时间就是金钱的观念 我决定通过windows模拟输入实现快速通过命令行查看mysql数据库 涉及到的知识: windows拉起进程&#xff0c;…

无线耳机能不能设计成我想象的这样的?

市面上有没有这种耳钉式的无线耳机啊&#xff0c;有的话能推荐一下吗&#xff1f;没有的话无线耳机的厂家能不能考虑一下这个方案&#xff0c;这样我们女生带耳机穿衣服或者梳头发的时候就不用摘下来了&#xff0c;也不会经常到处找耳机了 这样既能当耳机&#xff0c;又能做装…

测试 c++ 之 is_function_v

如图&#xff0c;给 is_function_v 传入一个类&#xff0c;为假&#xff0c;传入一个函数对象则为真 。 &#xff08;2&#xff09;以下是文心一言的解释&#xff0c;真好&#xff1a; 在 C 中&#xff0c;std::is_function_v 是一个类型特征&#xff08;type trait&#xff09…

数组和指针笔试题解析之【数组】

前言&#xff1a; 1.数组名的意义&#xff1a; sizeof(数组名)&#xff1a;这里的数组名表示整个数组&#xff0c;计算的是整个数组的大小&#xff0c;单位是字节。&数组名&#xff1a;这里的数组名表示整个数组&#xff0c;取出的是整个数组的地址。除此之外所有的数组名都…