• QShareMemory


    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

  • 相关阅读:
    正交实验
    边界值
    等价类划分概述
    测试用例编写
    java基础复习(四)
    easyui datagrid 搜索功能
    一段代码把网站变成灰白色
    PHP 获取二维数组中某个key的集合
    如何使用Mobile_Detect来判断访问网站的设备:安卓,平板,电脑
    easyui validatebox 验证类型
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/11061005.html
Copyright © 2020-2023  润新知