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的更多相关文章
随机推荐
- Github相关问题集锦
问题 对于我们国内用户,有时候浏览器在进入github网站时,会出现无法加载或加载很慢的问题,针对这一问题,很是头疼,为解决这一问题,在网上搜索到的解决方法如下: 解决方案 修改hosts文件,在ho ...
- OpenCV学习笔记5
OpenCV学习笔记5 图像变换 傅里叶变换 这里可以先学习一下卷积分,了解清除卷积的过程和实际意义,在看这一章节的内容. 原理: 傅里叶变换经常被用来分析不同滤波器的频率特性.我们可以使用 2D 离 ...
- Linux 内核错误码
#define EPERM 1 /* Operation not permitted */#define ENOENT 2 /* No such ...
- react实现设置答题器选项个数
一,设置答题器选项import React, { useState, useEffect } from 'react' import PropTypes from 'prop-types' impor ...
- 运输计划[二分答案 LCA 树上差分]
也许更好的阅读体验 \(\mathcal{Description}\) 原题链接 概括一下题意 给一颗有\(n\)个点带边权的树,有\(m\)个询问,每次询问\(u,v\)两点间的权值和,你可以将树中 ...
- manacher 算法(最长回文串)
manacher算法: 定义数组p[i]表示以i为中心的(包含i这个字符)回文串半径长 将字符串s从前扫到后for(int i=0;i<strlen(s);++i)来计算p[i],则最大的p[i ...
- 搭建一个简单的React项目
我是使用了create-react-app来搭建的基本框架,其中的原理和vue-cli差不多的脚手架.(当然也可以自己配置项目目录,这里我偷了一下懒) npm install -g create-re ...
- 如何使用async和await这对组合设计统一的取Access Token的函数
最近我在使用SAP云平台的机器学习API做和SAP系统的集成,因为SAP Cloud Platform Leonardo上的机器学期API,每次消费时需要传一个Access Token,故在每次实际调 ...
- 7层网络以及5种Linux IO模型以及相应IO基础
一.七层网络模型 OSI是Open System Interconnection的缩写,意为开放式系统互联.国际标准化组织(ISO)制定了OSI模型,该模型定义了不同计算机互联的标准,它是一个七层的. ...
- mysql数据库的多实例与主从同步。
1.MySQL的多实例: 多实例的特点:能够有效地利用服务器的资源,节约服务器的资源 MySQL多实例的配置有两种,第一是使用一个配置文件,这种方法不推荐使用,容易出错:第二种是用多个配置文件,这种方 ...