Qt提供了一种安全的共享内存的实现QSharedMemory,以便在多线程和多进程编程中安全的使用。比如说QQ的聊天的客户端,这里有个个性头象,当点击QQ音乐播放器的时候,启动QQ音乐播放器(启动一QQ音乐播放器的进程)这时QQ音乐播放器里也有一个个性头像,这两者间的头像一样,现用共享内存的方法实现。
    先说下实现共享内存的步骤,然后用一具体的实例说明。
向共享内存中提供数据的一方:
    1,定义QSharedMemory shareMemory,并设置标志名shareMemory.setKey();
     2,将共享内存与主进程分离 shareMemory.detach();
    3,创建共享内存 shareMemory.create();
     4,将共享内存上锁shareMemory.lock();
     5,将进程中要共享的数据拷贝到共享内存中;
     6,将共享内存解锁shareMemory.unlock();
从共享内存中取数据的一方:
    1,定义QSharedMemory shareMemory,并设置共享内存的标志名shareMemory.setKey()注意设置的要与提供内存共享的一方要一样。
    2,将共享内存上锁shareMemory.lock();
    3,将共享内存与主进程绑定shareMemory.attach(),使该进程可以访问共享内存的数据;
    4,从共享内存中取数据;
    5,使用完后将共享内存解锁shareMemory.unlock(),另外将共享内存与该进程分离shareMemory.detach();

下面贴段代码来说明:
A 向共享内存中提供数据的一方
[html] view plaincopy
main.cpp  
#include <QtGui/QApplication>  
#include "widget.h"  
  
int main(int argc, char *argv[])  
{  
    QApplication a(argc, argv);  
    Widget w;  
    w.show();    
    return a.exec();  
}

[html] view plaincopy
widget.h  
ifndef WIDGET_H  
#define WIDGET_H  
  
#include <QWidget>  
#include <QSharedMemory>  
  
namespace Ui {  
class Widget;  
}  
  
class Widget : public QWidget  
{  
    Q_OBJECT  
      
public:  
    explicit Widget(QWidget *parent = 0);  
    ~Widget();  
      
private slots:  
    void on_pushButton_clicked();  
  
    void on_pushButton_2_clicked();  
  
private:  
    Ui::Widget *ui;  
    QSharedMemory shareMemory;//注意该变量不要在函数内局部定义,由于函数内的局部变量随着函数执行结束而消失  
};  
  
#endif // WIDGET_H

[html] view plaincopy
widget.cpp  
  
#include "widget.h"  
#include "ui_widget.h"  
#include <QFileDialog>  
#include <QBuffer>  
#include <QDebug>  
#include <QProcess>  
  
Widget::Widget(QWidget *parent) :  
    QWidget(parent),  
    ui(new Ui::Widget)  
{  
    ui->setupUi(this);  
    shareMemory.setKey("share");  
}  
  
Widget::~Widget()  
{  
    delete ui;  
}  
  
void Widget::on_pushButton_clicked()  
{  
    if(shareMemory.isAttached())  
    {  
        shareMemory.detach();//将该进程与共享内存段分离  
    }  
    QString filename = QFileDialog::getOpenFileName(this);  
    QPixmap pixMap;  
    pixMap.load(filename);  
    ui->label->setPixmap(pixMap);  
  
    QBuffer buffer;  
    QDataStream out(&buffer);  
    buffer.open(QBuffer::ReadWrite);  
    out<<pixMap;  
    qDebug()<<buffer.size();  
    int size = buffer.size();  
    if(!shareMemory.create(size))  
    {  
        qDebug()<<tr("can't create memory segment");  
        qDebug()<<shareMemory.error();  
        return;  
    }  
    qDebug()<<shareMemory.size();  
    shareMemory.lock();  
    char *to = (char*)shareMemory.data();  
    const char *from = (char*)buffer.data().data();  
    memcpy(to,from,qMin(size,shareMemory.size()));//数据从该进程中拷贝到共享数据内存中  
    shareMemory.unlock();//共享内层解锁  
}  
B 从共享内存中取数据的一方:
[cpp] view plaincopy
main.cpp  
  
#include <QtGui/QApplication>  
#include "widget.h"  
  
int main(int argc, char *argv[])  
{  
    QApplication a(argc, argv);  
    Widget w;  
    w.show();  
      
    return a.exec();  
}

[cpp] view plaincopy
widget.h  
  
#ifndef WIDGET_H  
#define WIDGET_H  
  
#include <QWidget>  
#include <QSharedMemory>  
  
namespace Ui {  
class Widget;  
}  
  
class Widget : public QWidget  
{  
    Q_OBJECT  
      
public:  
    explicit Widget(QWidget *parent = 0);  
    ~Widget();  
      
private slots:  
    void on_pushButton_clicked();  
  
private:  
    Ui::Widget *ui;  
    QSharedMemory shareMemory;  
};  
  
#endif // WIDGET_H

[cpp] view plaincopy
widget.cpp  
  
#include "widget.h"  
#include "ui_widget.h"  
#include <QBuffer>  
#include <QDebug>  
  
  
Widget::Widget(QWidget *parent) :  
    QWidget(parent),  
    ui(new Ui::Widget)  
{  
    ui->setupUi(this);  
    shareMemory.setKey("share");//设置标志一定要与共享内存的标志一样  
    this->on_pushButton_clicked();  
}  
  
Widget::~Widget()  
{  
    delete ui;  
}  
  
void Widget::on_pushButton_clicked()  
{  
    if(!shareMemory.attach())//将shareMemory与该进程绑定使之可以访问shareMemory里的内容  
    {  
        qDebug()<<tr("can't attach share memory");  
    }  
    QBuffer buffer;  
    QDataStream in(&buffer);  
    QPixmap pixMap;  
    shareMemory.lock();//给shareMemory枷锁  
    qDebug()<<shareMemory.size();  
    buffer.setData((char*)shareMemory.constData(),shareMemory.size());//将shareMemeory里的数据放到buffer里  
    buffer.open(QBuffer::ReadWrite);  
    in>>pixMap;  
    shareMemory.unlock();//将shareMemory解锁  
    shareMemory.detach();//将shareMemeory与该进程分离  
    ui->label->setPixmap(pixMap);  
}

原文地址:https://blog.csdn.net/gzfstudy/article/details/38228013

QShareMemory的更多相关文章

随机推荐

  1. vue导入css,js和放置html代码

    使用场景:我是从网上找的html前端页面模板,导入找的模板中的css和js到vue中使用. 1.在main.js中全局导入css和js import '@/assets/css/main.css' i ...

  2. 暑期ACM集训

    2019-07-17 08:42:11 这是总结昨天的做题情况 总体来说,好久的没做题了,实力下降了许多,这一个月假又学习吧!!!! A - Ropewalkers Polycarp decided ...

  3. 解决Html页面缓存

    对于一个html页面,缓存分3部分,一个是页面内容,一个是css样式,一个是JS文件 CSS和JS文件缓存 <link rel="stylesheet" type=" ...

  4. Vuex 刷新后数据丢失问题 Typescript

    问题描述:Vuex保存的数据在页面刷新后会全部丢失清除 问题解决方案:使用sessionstorage进行保存,在页面刷新时保存至sessionStorage,页面在加载时再进行填充   (另有vue ...

  5. Node.js 实战(一)之—优化汇总

    Express 页面缓存 app.set("cache view",true); --设置页面缓存 开发模式下博主建议不要这么做,因为开发中我们会频繁的对页面的样式.js等进行修改 ...

  6. (详细)Eclips+jsp+servlet+mysql+登录实例+源代码

    欢迎任何形式的转载,但请务必注明出处. 该教程较全,从软件的安装以及相关的环境配置我都放置了相关教程的链接,读者可直接点击进入.自己写电商网站作业时查找了很多资料,但都不是很全,所以趁着寒假写了这份教 ...

  7. [转]預防 Android Dex 64k Method Size Limit

    转载自:http://ingramchen.io/blog/2014/09/prevention-of-android-dex-64k-method-size-limit.html 08 Septem ...

  8. Nginx作为缓存服务

    缓存类型 (1) 服务器缓存 服务端缓存一般使用Memcache.Redis (2)代理缓存 (3)客户端缓存 代理缓存流程图 第一步:客户端第一次向Nginx请求数据a: 第二步:当Nginx发现缓 ...

  9. centos 7.6 配置VNC

    一.安装 1.  以root用户运行以下命令来安装vncserver; yum install tigervnc-server 2.  同样运行以下命令来安装vncviewer; yum instal ...

  10. CentOS7安装CDH 第十三章:CDH资源池配置

    相关文章链接 CentOS7安装CDH 第一章:CentOS7系统安装 CentOS7安装CDH 第二章:CentOS7各个软件安装和启动 CentOS7安装CDH 第三章:CDH中的问题和解决方法 ...