Qt进程通信之共享内存(QSharedMemory)-程序员宅基地

技术标签: c++  QT  qt  c/c++  

首先介绍下什么是共享内存。
定义:
共享内存指 (shared memory)在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否则不同的处理器可能用到不同的数据。共享内存是 Unix下的多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。
应用场景:
1、进程间通信。
两个进程同时挂载一片共享内存,进程A写、进程B读,就达到了通信效果,这种方案的好处是,读写都是基于内存操作,效率非常之高。
2、数据共享。
类似于读写锁中的读锁原理。这里是一个进程写了后,其它多个相同的进程进行读取这片数据。比如A进程写数据到共享内存,B、C进程从共享内存读取这片数据。
3、单进程数据缓存。
比如单机上只有一个实例,该实例需要在启动的时候加载一大块资源到内存,那么,如果基于共享内存,将资源加载到共享内存,那么,下次启动的时候,只要version或者crc没变,就可以直接挂载使用,无需再次读入。比如程序启动需要加载cpu型号、内存信息、系统属性、配置文件数据等等时,软件第一次启动时先将数据加载到共享内存,后面启动时只需要从共享内存读取数据,提升程序的启动速度。
4、保证软件不重复启动。
通过共享内存绑定程序,再次启动这个程序时,进行判断该共享内存是否被绑定,是否还能够再次创建成功,来防止软件重复启动。

这里只展示场景1、2、4的代码示例。
场景1和场景2:
进程A写共享内存。

        m_shareMemory.setKey("shared momery");
        if(m_shareMemory.isAttached())
             m_shareMemory.detach();//将该进程与共享内存段分离
        QBuffer buffer;     //创建缓冲区绑定数据流,然后通过数据流写数据,这样能保证数据的格协议式和编码格式不被干扰。
        QDataStream in(&buffer);
        buffer.open(QBuffer::ReadWrite);
        in<<“test data”;
        int size = buffer.size();
        if(!m_shareMemory.create(size))
        {
            qDebug()<<"can't create memory segment"<<m_shareMemory.error();
        }
        m_shareMemory.lock();
        char *to = (char*)m_shareMemory.data();
        const char *from = (char*)buffer.data().data();
        memcpy(to,from,qMin(size,m_shareMemory.size()));//数据从该进程中拷贝到共享数据内存中
        m_shareMemory.unlock();//共享内层解锁
        m_shareMemory.detach();
    }

进程B读共享内存

    m_shareMemory.setKey("shared momery");
    if(!m_shareMemory.attach())//将shareMemory与该进程绑定使之可以访问shareMemory里的内容
    {
        qDebug()<<tr("can't attach share memory");
        m_shareMemory.detach();//将shareMemeory与该进程分离
    }
    if (m_shareMemory.isAttached())
    {
        QByteArray data;
        QBuffer buffer;  /创建缓冲区绑定数据流,同样通过数据流读数据。这里buffer可以不通过数据流拿数据,但是这样会造成数据的格式变化。
        QDataStream out(&buffer);
        m_shareMemory.lock();//给shareMemory加锁
        buffer.setData((char*)m_shareMemory.constData(),m_shareMemory.size());//将shareMemeory里的数据放到buffer里
        buffer.open(QBuffer::ReadWrite);
        out>>data;
        qDebug()<<data;
        m_shareMemory.unlock();//将shareMemory解锁
        m_shareMemory.detach();
    }

进程C读数据

#include "widget.h"
#include "ui_widget.h"
#include <QBuffer>
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    startTimer(1000);
    m_shareMemory.setKey("shared momery");
    if (!m_shareMemory.attach())
    {
        qDebug()<<"attach is failed ";
        m_shareMemory.detach();
    }
}

Widget::~Widget()
{
    delete ui;
}

void Widget::timerEvent(QTimerEvent *event)
{
    QByteArray array;
    QBuffer buffer;
    QDataStream out(&buffer);
    m_shareMemory.lock();
    buffer.setData((char*)m_shareMemory.constData(),m_shareMemory.size());
    buffer.open(QBuffer::ReadWrite);
    out>>array;
    qDebug()<<array;
    m_shareMemory.unlock();
}

场景4:代码介绍

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43246170/article/details/129242219

智能推荐

java Spring Boot整合jwt实现token生成_springboot项目生成token-程序员宅基地

文章浏览阅读1k次。这里 我是直接不管了 不管他传什么进来 只要是符合我users类格式的 我就算他登录通过 通过getid生成一个token 返回回去。然后 这里 我们加一个属性类 用于用户登录使用 这里 我就搞简单一点 直接 一个id 一个name了。这里需要注意的是 如果你想通过id生成token 那么 你的id必须是个字符串。因为登录接口要用 JwtUtils 所以 最好建在登录接口的类的同目录下。然后 我们接口所在的类 要条件装配好我们用户的属性类 也就是 users。_springboot项目生成token

Android Studio真机调试教程_android studio 配置调试机-程序员宅基地

文章浏览阅读508次,点赞4次,收藏10次。进行USB连接的真机调试,将你写的安卓程序安装到安卓手机、平板。在目标安卓终端和AS进行一些设置。我的设备信息:Android设备:MatePad10.4 Mate40e版本:鸿蒙3.0 / 鸿蒙4.0 对应安卓下载10.0版本即可(只要是鸿蒙系统一般都是下载10.0)_android studio 配置调试机

get新技能!把学校饭卡复制到小米手环NFC版本上_nfc_reader_crack-程序员宅基地

文章浏览阅读7.8k次,点赞3次,收藏32次。*严正声明:本文仅限于技术讨论与分享,严禁用于非法途径。hello!大家好,欢迎来到网络安全情报局,网络安全特工将持续为您分享最新资讯、干货。也可以关注我的公众号:网络安全情报局,获取最新消息。一、NFC是什么?NFC是Near Field Communication缩写,即近距离无线通讯技术。由飞利浦公司和索尼公司共同开发的NFC是一种非接触式识别和互联技术,可以在移动设备、消费类电子产品、PC和智能控件工具间进行近距离无线通信。NFC功能提供了一种简单、触控式的解决方案,可以让消费者简单_nfc_reader_crack

[转]Discuz! X3.0最新研发进度【提前预览】_discuzx3.0-程序员宅基地

文章浏览阅读1.2k次。【Discuz! X3.0研发进度-曝光】1、离Discuz! X2.5发布已有半年时间,很多站长和我一样,想了解下Discuz!产品的最新动态,咱们研发团队最近都在忙什么呢?  这段时间我们把主要精力放在了Discuz! 新产品的研发上了,在优化和完善Discuz! X2.5百项功能的基础上,开发Discuz! X3.0,目前Discuz! X3.0已进入最后攻坚阶段_discuzx3.0

DB2对SEQUENCE进行授权_db2 sequence授权-程序员宅基地

文章浏览阅读1k次。场景:在A模式下创建了序列TEST_SEQ,但是当B模式使用该序列时发现报错。此时就需要对B模式授权。具体步骤如下A模式下执行授权:grant usage on sequence igw.TEST_SEQ to ipay;B模式下创建别名:create or replace alias ipay.TEST_SEQ for sequence igw.TEST_SEQ这样模式A和B可以共用..._db2 sequence授权

qt5.9+vtk7.1.1+pcl1.8.1(使用qvtkWidget控件显示)_#include "qvtkwidget.h-程序员宅基地

文章浏览阅读571次,点赞3次,收藏3次。1.new file or project2.Qt Console A…3.add qvtkWidget.proSOURCES += \ main.cpp \ mainwindow.cppHEADERS += \ mainwindow.hFORMS += \ mainwindow.uiINCLUDEPATH += /usr/include/eigen3INCLUDEPATH += /usr/local/include/v_#include "qvtkwidget.h

随便推点

【机器学习】高斯回归过程GPR_高斯过程回归 kriging-程序员宅基地

文章浏览阅读418次。我是知识的搬运工_高斯过程回归 kriging

[Win32SDK基本]ListView Controls(1)Report (details) View 详解_syslistview32l 换行-程序员宅基地

文章浏览阅读7k次,点赞5次,收藏16次。本文由CSDN用户zuishiko所作,转载请注明出处:http://blog.csdn.net/zuishikonghuan/article/details/46872885老规矩,先上MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/bb774737(v=vs.85).aspx其实还是子窗口,static那节_syslistview32l 换行

QT 网络编程(一)-程序员宅基地

文章浏览阅读1.1k次,点赞38次,收藏20次。Qt 网络编程相关

软工视频总结-程序员宅基地

文章浏览阅读614次。经过十天的时间,对软工视频进行一下简单的总结。软工视频总共有24讲,一讲大约50分钟。前3章介绍软工视频的历史。 第 6 讲 1.需求分析的任务就是借助于当前系统的逻辑模型导出目标系统的逻辑模型,解决,目标系统的“做什么”的问题。 2.问题识别的另一项工作是建立分析所需要的通信途径,以保证能顺利地对问题进行分析。

python bad magic number_科学网-python反编译软件推荐uncompyle6-Bad magic number in .pyc-陈照强的博文...-程序员宅基地

文章浏览阅读2.6k次。背景从友方那边获得了pyc文件,但是由于他当时用的是python2.6编译的,而现在python2.6几乎被淘汰掉了,安装了python2.7 等其他版本无法运行该pyc文件,报错 RuntimeError: Bad magic number in .pyc file 。安装了python 2.6 后,运行该文件不报错,但是依赖模块openbabel,openbabel在python2.6中安装稍..._bad magic number in .pyc file

C语言中的数组(1)-程序员宅基地

文章浏览阅读902次,点赞29次,收藏17次。一维数组的创建和初始化,一维数组的使用,一维数组在内存中的存储,以及计算数组元素的个数的方法。

推荐文章

热门文章

相关标签