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的更多相关文章
随机推荐
- Oracle 11g xe版本---总结1
一.创建用户和授予权限 1.1 环境: Oracle 11g xe 第三方图形客户端: PLSQL Windows 10 必须登录 HR 用户,下面的查询会使用到 HR 中的表. 1.2 SQL 语句 ...
- 音视频入门-07-认识YUV
* 音视频入门文章目录 * YUV & YCbCr 简介 YUV,是一种颜色编码方法.常使用在各个视频处理组件中. YUV 在对照片或视频编码时,考虑到人类的感知能力,允许降低色度的带宽. Y ...
- 升级win10 1903版后,vmware打开虚拟机黑屏的解决办法
按照网上给的方法(1-3),又增加了几步(从4开始,只在我自己电脑上实践过): 1. 打开cmd,执行以下命令 netsh winsock reset 2. 重启电脑 3. 以管理员身份执行vmwar ...
- core直接获取报异常数据
报异常直接跳转到/Home/Error [ResponseCache(Duration = , Location = ResponseCacheLocation.None, NoStore = tru ...
- 【转载】腾讯云安全组如何开放3306端口让Mysql可访问
Mysql数据库的默认端口号为3306,在服务器安装好Mysql数据库后,如果使用的服务器是阿里云或者腾讯云服务器,如果在后台启用了安全组功能,则需要在安全组中对3306端口的入站规则进行放行,只有在 ...
- vue中组件之间的通信
一.vue中组件通信的种类 父组件向子组件的通信 子组件向父组件的通信 隔代组件之间的通信 兄弟 组件 之间的通信 二.实现通信的方式 props vue自定义的事件 消息订阅与发布 vuex sl ...
- SVM-支持向量机总结
一.SVM简介 (一)Support Vector Machine 支持向量机(SVM:Support Vector Machine)是机器学习中常见的一种分类算法. 线性分类器,也可以叫做感知机,其 ...
- iOS CALayer总结——图层几何
最近看了一下关于图层和动画的内容,所以写了一份总结,算是对这些内容的汇总吧,都是一些简单的基础知识,不知道大家都了不了解. 除了和用户的交互之外,图层的很多属性和视图基本上都是一样的,今天就先从CAL ...
- pandas(四)
合并 merge,concat,join pd.merge(df1,df2,on=‘列名’,how='') df1.join(df2,how='outer',on='') pd.concat([df ...
- linux reboot ,shutdown,halt区别
reboot ,shutdown,halt区别 重启 reboot 和 shutdown -r now 效果是一样的都是重启 区别在于reboot 是重启时,删除所有的进程,为不是平稳的终止他 ...