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
QShareMemory的更多相关文章
随机推荐
- Python进阶: Decorator 装饰器你太美
函数 -> 装饰器 函数的4个核心概念 1.函数可以赋与变量 def func(message): print('Got a message: {}'.format(message)) send ...
- WUSTOJ 1319: 球(Java)并查集
题目链接:1319: 球 参考:wustoj 1319 球-wust_tanyao,并查集 并查集系列:WUSTOJ 1346: DARK SOULS(Java)并查集 Description Icy ...
- WUSTOJ 1311: 开心的金明(Java)动态规划-01背包
题目链接:
- Linux磁盘管理系列 — LVM和RAID
一.逻辑卷管理器(LVM) 1.什么是逻辑卷管理器(LVM) LVM是逻辑盘卷管理(Logical Volume Manager)的简称,它是Linux环境下对卷进行操作的抽象层. LVM是建立在硬盘 ...
- 用chattr命令防止系统中某个关键文件被修改
用chattr命令防止系统中某个关键文件被修改:# chattr +i /etc/resolv.conf
- C#方法(用法,参数)
方法:是一种用于实现可以由对象或类执行的计算或操作的成员,是一个已命名的语句集.方法就是把一些相关的语句组织到一起,用来执行一个任务的语句块.比如每个C#程序至少带一个main函数 1.格式:修饰符 ...
- snort_inline
snort_inline Link http://snort-inline.sourceforge.net/oldhome.html What is snort_inline? snort_inl ...
- js数组实现上移下移
up(index) { if(index === 0) { return } //在上一项插入该项 this.list.splice(index - 1, 0, (this.list[index])) ...
- 简单记录一次注入到shell
0x00 前言 帮朋友之前拿的一个站,有点久了没有完整截图,简单记录一下. 0x01 基础信息 操作系统:win 集成环境:phpstudy 端口开放:82,3306,3389 有phpmyadmin ...
- JAVA中为什么要使用接口,继承接口不是还要重写方法吗?为什么不直接写那些方法呢?:::接口的最主要的作用是达到统一访问
接口的最主要的作用是达到统一访问 那么什么叫统一访问呢 举个例子 你这样想,我做一个USB接口,有个读的抽象方法 那叫read()吧,然后mp3类实现,U盘类实现,移动硬盘类实现,这样我用的时候用US ...