QT 进程间通信之古老的方法(内存共享)

QT 进程间通信之古老的方法(内存共享)

  9086人阅读  评论(3)  收藏  举报
  分类:

      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 plain  copy
  1. main.cpp  
  2. #include <QtGui/QApplication>  
  3. #include "widget.h"  
  4.   
  5. int main(int argc, char *argv[])  
  6. {  
  7.     QApplication a(argc, argv);  
  8.     Widget w;  
  9.     w.show();    
  10.     return a.exec();  
  11. }  

[html]  view plain  copy
  1. widget.h  
  2. ifndef WIDGET_H  
  3. #define WIDGET_H  
  4.   
  5. #include <QWidget>  
  6. #include <QSharedMemory>  
  7.   
  8. namespace Ui {  
  9. class Widget;  
  10. }  
  11.   
  12. class Widget : public QWidget  
  13. {  
  14.     Q_OBJECT  
  15.       
  16. public:  
  17.     explicit Widget(QWidget *parent = 0);  
  18.     ~Widget();  
  19.       
  20. private slots:  
  21.     void on_pushButton_clicked();  
  22.   
  23.     void on_pushButton_2_clicked();  
  24.   
  25. private:  
  26.     Ui::Widget *ui;  
  27.     QSharedMemory shareMemory;//注意该变量不要在函数内局部定义,由于函数内的局部变量随着函数执行结束而消失  
  28. };  
  29.   
  30. #endif // WIDGET_H  

[html]  view plain  copy
  1. widget.cpp  
  2.   
  3. #include "widget.h"  
  4. #include "ui_widget.h"  
  5. #include <QFileDialog>  
  6. #include <QBuffer>  
  7. #include <QDebug>  
  8. #include <QProcess>  
  9.   
  10. Widget::Widget(QWidget *parent) :  
  11.     QWidget(parent),  
  12.     ui(new Ui::Widget)  
  13. {  
  14.     ui->setupUi(this);  
  15.     shareMemory.setKey("share");  
  16. }  
  17.   
  18. Widget::~Widget()  
  19. {  
  20.     delete ui;  
  21. }  
  22.   
  23. void Widget::on_pushButton_clicked()  
  24. {  
  25.     if(shareMemory.isAttached())  
  26.     {  
  27.         shareMemory.detach();//将该进程与共享内存段分离  
  28.     }  
  29.     QString filename = QFileDialog::getOpenFileName(this);  
  30.     QPixmap pixMap;  
  31.     pixMap.load(filename);  
  32.     ui->label->setPixmap(pixMap);  
  33.   
  34.     QBuffer buffer;  
  35.     QDataStream out(&buffer);  
  36.     buffer.open(QBuffer::ReadWrite);  
  37.     out<<pixMap;  
  38.     qDebug()<<buffer.size();  
  39.     int size = buffer.size();  
  40.     if(!shareMemory.create(size))  
  41.     {  
  42.         qDebug()<<tr("can't create memory segment");  
  43.         qDebug()<<shareMemory.error();  
  44.         return;  
  45.     }  
  46.     qDebug()<<shareMemory.size();  
  47.     shareMemory.lock();  
  48.     char *to = (char*)shareMemory.data();  
  49.     const char *from = (char*)buffer.data().data();  
  50.     memcpy(to,from,qMin(size,shareMemory.size()));//数据从该进程中拷贝到共享数据内存中  
  51.     shareMemory.unlock();//共享内层解锁  
  52. }  

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

[cpp]  view plain  copy
  1. main.cpp  
  2.   
  3. #include <QtGui/QApplication>  
  4. #include "widget.h"  
  5.   
  6. int main(int argc, char *argv[])  
  7. {  
  8.     QApplication a(argc, argv);  
  9.     Widget w;  
  10.     w.show();  
  11.       
  12.     return a.exec();  
  13. }  

[cpp]  view plain  copy
  1. widget.h  
  2.   
  3. #ifndef WIDGET_H  
  4. #define WIDGET_H  
  5.   
  6. #include <QWidget>  
  7. #include <QSharedMemory>  
  8.   
  9. namespace Ui {  
  10. class Widget;  
  11. }  
  12.   
  13. class Widget : public QWidget  
  14. {  
  15.     Q_OBJECT  
  16.       
  17. public:  
  18.     explicit Widget(QWidget *parent = 0);  
  19.     ~Widget();  
  20.       
  21. private slots:  
  22.     void on_pushButton_clicked();  
  23.   
  24. private:  
  25.     Ui::Widget *ui;  
  26.     QSharedMemory shareMemory;  
  27. };  
  28.   
  29. #endif // WIDGET_H  

[cpp]  view plain  copy
  1. widget.cpp  
  2.   
  3. #include "widget.h"  
  4. #include "ui_widget.h"  
  5. #include <QBuffer>  
  6. #include <QDebug>  
  7.   
  8.   
  9. Widget::Widget(QWidget *parent) :  
  10.     QWidget(parent),  
  11.     ui(new Ui::Widget)  
  12. {  
  13.     ui->setupUi(this);  
  14.     shareMemory.setKey("share");//设置标志一定要与共享内存的标志一样  
  15.     this->on_pushButton_clicked();  
  16. }  
  17.   
  18. Widget::~Widget()  
  19. {  
  20.     delete ui;  
  21. }  
  22.   
  23. void Widget::on_pushButton_clicked()  
  24. {  
  25.     if(!shareMemory.attach())//将shareMemory与该进程绑定使之可以访问shareMemory里的内容  
  26.     {  
  27.         qDebug()<<tr("can't attach share memory");  
  28.     }  
  29.     QBuffer buffer;  
  30.     QDataStream in(&buffer);  
  31.     QPixmap pixMap;  
  32.     shareMemory.lock();//给shareMemory枷锁  
  33.     qDebug()<<shareMemory.size();  
  34.     buffer.setData((char*)shareMemory.constData(),shareMemory.size());//将shareMemeory里的数据放到buffer里  
  35.     buffer.open(QBuffer::ReadWrite);  
  36.     in>>pixMap;  
  37.     shareMemory.unlock();//将shareMemory解锁  
  38.     shareMemory.detach();//将shareMemeory与该进程分离  
  39.     ui->label->setPixmap(pixMap);  
  40. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值