00. 目录

文章目录

  • 00. 目录
  • 01. 概述
  • 02. 公有类型
  • 03. 成员方法
  • 04. 程序示例一
  • 05. 程序示例二
  • 06. 源码下载
  • 07. 附录

01. 概述

QSharedMemory提供了多个线程和进程对共享内存段的访问。它还提供了一种方法,让单个线程或进程锁定内存以进行独占访问。

当使用这个共享内存类时,请注意以下平台差异:

Windows:QSharedMemory 不“拥有”共享内存段。当所有具有连接到特定共享内存段的 QSharedMemory 实例的线程或进程已销毁其 QSharedMemory 实例或退出时,Windows 内核会自动释放共享内存段。

Unix:QSharedMemory“拥有”共享内存段。当将 QSharedMemory 实例附加到特定共享内存段的最后一个线程或进程通过销毁其 QSharedMemory 实例与该段分离时,Unix 内核会释放共享内存段。但是如果最后一个线程或进程在没有运行 QSharedMemory 析构函数的情况下崩溃,共享内存段会在崩溃中幸存下来。

HP-UX:每个进程只允许一个连接到共享内存段。这意味着 QSharedMemory 不应跨 HP-UX 中同一进程中的多个线程使用。

记得在对共享内存进行读写之前用lock ()锁住共享内存,完成后记得用unlock ()释放锁。

当 QSharedMemory 的最后一个实例与段分离时,QSharedMemory 会自动销毁共享内存段,并且不会保留对该段的引用。

警告

除非另有说明,否则 QSharedMemory 以特定于 Qt 的方式更改密钥。与非 Qt 应用程序的互操作是通过首先使用 QSharedMemory() 创建默认共享内存,然后使用 setNativeKey() 设置本机密钥来实现的。使用本机密钥时,共享内存不受对其多次访问的保护(例如,无法锁定()),应使用用户定义的机制来实现这种保护。

02. 公有类型

03. 成员方法

成员方法概述

QSharedMemory::QSharedMemory(const QString &key, QObject *parent = nullptr)
使用给定的父对象构造一个共享内存对象,并将其键设置为key。因为它的key被设置了,它的create ()和
attach ()函数就可以调用了。    QSharedMemory::QSharedMemory(QObject *parent = nullptr)
此函数重载 QSharedMemory()。
使用给定的parent构造一个共享内存对象。共享内存对象的键不是由构造函数设置的,因此共享内存对象没有附加底层共享内存段。
在调用`create()`或者attach()之前必须使用setKey()或者setNativeKey()设置Key.[virtual] QSharedMemory::~QSharedMemory()
析构函数清除Key,这会强制共享内存对象与其底层共享内存段分离。如果此共享内存对象是最后一个连接到共享内存段的对象,
则detach () 操作会销毁共享内存段。bool QSharedMemory::attach(QSharedMemory::AccessMode mode = ReadWrite)
尝试将进程关联到由传递给构造函数或调用setKey () 或setNativeKey ()的密钥标识的共享内存段。
访问方式默认为ReadWrite。
它也可以是ReadOnly。true如果附加操作成功则返回。如果返回false,则调用error ()来判断发生了哪个错误。
附加共享内存段后,
可以通过调用data ()获得共享内存的指针。    const void *QSharedMemory::constData() const
返回一个指向共享内存段内容的常量指针,如果有的话。否则返回空值。记得在对共享内存进行读写之前用lock ()锁住共享内存,
完成后记得用unlock ()释放锁。bool QSharedMemory::create(int size, QSharedMemory::AccessMode mode = ReadWrite)
使用传递给构造函数的键创建大小为size字节的共享内存段,使用setKey () 或使用setNativeKey ()设置key,
然后使用给定的访问模式
关联到新的共享内存段并返回true。如果key标识的共享内存段已经存在,则不执行attach操作并false返回。当返回值为 时false,
调用error ()来判断发生了哪个错误。    void *QSharedMemory::data()
返回一个指向共享内存段内容的指针,如果有的话。否则返回空值。记得在对共享内存进行读写之前用lock ()锁住共享内存,
完成后记得用unlock ()释放锁。const void *QSharedMemory::data() const
此函数重载 data()。bool QSharedMemory::detach()
从共享内存段中分离进程。如果这是最后一个附加到共享内存段的进程,那么共享内存段将被系统释放,即内容被销毁。
true如果它分离共享内存段,则该函数返回。如果它返回false,通常意味着该段没有被附加,或者它被另一个进程锁定。QSharedMemory::SharedMemoryError QSharedMemory::error() const
返回一个值,该值指示是否发生了错误,如果发生了,则是哪个错误。QString QSharedMemory::errorString() const
返回最后发生的错误的文本描述。如果error () 返回错误值,则调用此函数以获取描述错误的文本字符串。bool QSharedMemory::isAttached() const
返回true此进程是否附加到共享内存段。QString QSharedMemory::key() const
返回用setKey ()分配给这个共享内存的键,如果没有分配键,或者段使用nativeKey () ,则返回空键。
密钥是 Qt 应用程序用来标识共享内存段的标识符。您可以通过调用nativeKey ()找到操作系统使用的本机、特定于平台的key。    bool QSharedMemory::lock()
这是一个信号量,它锁定共享内存段以供此进程访问并返回true。如果另一个进程锁定了该段,则该函数将阻塞,
直到锁定被释放。然后它获取锁并返回true。如果此函数返回false,则表示您忽略了来自create () 或attach ()
的 false 返回,您已使用setNativeKey ()设置key或QSystemSemaphore::acquire () 由于未知系统错误而失败。    QString QSharedMemory::nativeKey() const
返回此共享内存对象的本机、特定于平台的key。本机key是操作系统用来标识共享内存段的标识符。
您可以使用本机key访问不是由 Qt 创建的共享内存段,或授予非 Qt 应用程序共享内存访问权限。    void QSharedMemory::setKey(const QString &key)
为这个共享内存对象设置平台无关的键。如果key与当前 key 相同,则函数不执行任何操作就返回。
您可以调用key () 来检索平台无关的密钥。在内部,QSharedMemory将此密钥转换为特定于平台的密钥。
如果您改为调用nativeKey (),您将获得特定于平台的转换后的密钥。
如果共享内存对象附加到底层共享内存段,它将在设置新密钥之前与其分离。这个函数不做attach ()。void QSharedMemory::setNativeKey(const QString &key)
设置此共享内存对象的本机、特定于平台的键。如果key与当前本机 key 相同,则该函数不执行任何操作就返回。
如果您只想为段分配一个键,则应改为调用setKey ()。
您可以调用nativeKey () 来检索本机密钥。如果已分配本机键,则调用key () 将返回空字符串。
如果共享内存对象附加到底层共享内存段,它将在设置新密钥之前与其分离。这个函数不做attach ()。
如果您设置本机密钥,该应用程序将不可移植。int QSharedMemory::size() const
返回附加共享内存段的大小。如果没有附加共享内存段,则返回 0。
注意:段的大小可能大于传递给create ()的请求大小。bool QSharedMemory::unlock()
如果该进程当前持有该锁,则释放共享内存段上的锁并返回true。如果该段没有被锁定,或者如果该锁定被另一个进程持有,
则什么都不会发生并且返回 false。    

04. 程序示例一

程序示例

#include <QCoreApplication>#include <QSharedMemory>
#include <QDebug>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);//共享内存对象QSharedMemory shareMemory;//设置共享内存的键 没有设置key之前默认为空qDebug() << "Key: " << shareMemory.key();//设置共享内存的KeyshareMemory.setKey("Qt");qDebug() << "Key: " << shareMemory.key();//默认共享内存是没有关联的qDebug() << "isAttached: " << shareMemory.isAttached();//对应Key的共享内存不存在,因此关联失败qDebug() << shareMemory.attach();qDebug() << shareMemory.errorString();//判断该进程是否与共享内存关联if (shareMemory.isAttached()){if (!shareMemory.detach()){qDebug() << shareMemory.errorString();return -1;}}//默认读写的方式创建共享内存 创建的同时自动关联到该共享内存if (!shareMemory.create(1024)){qDebug() << shareMemory.errorString();return -1;}qDebug() << "isAttached: " << shareMemory.isAttached();qDebug() << "size: " << shareMemory.size();//加锁qDebug() << "lock: " << shareMemory.lock();//获取共享内存的起始地址void *data = shareMemory.data();qDebug() << "Addr: " << data;//拷贝数据memcpy(data, "hello", strlen("hello"));//解锁qDebug() << "unlock: " << shareMemory.unlock();//解除与共享内存的关联qDebug() << "detach: " << shareMemory.detach();return 0;
}

执行结果

Key:  ""
Key:  "Qt"
isAttached:  false
false
"QSharedMemory::handle: doesn't exist"
isAttached:  true
size:  4096
lock:  true
Addr:  0x29d0000
unlock:  true
detach:  true

05. 程序示例二

读写示例

#include <QCoreApplication>#include <QSharedMemory>
#include <QDebug>/*
编程思路共享内存中数据提供方:
A、定义QSharedMemory shareMemory,并设置标志名shareMemory.setKey();
B、将共享内存与主进程分离 shareMemory.detach();
C、创建共享内存 shareMemory.create();
D、将共享内存上锁shareMemory.lock();
E、将进程中要共享的数据拷贝到共享内存中;
F、将共享内存解锁shareMemory.unlock();共享内存中数据使用方:
A、定义QSharedMemory shareMemory,并设置与共享内存提供方一致的标志名shareMemory.setKey()。
B、将共享内存与主进程绑定shareMemory.attach(),使主进程可以访问共享内存的数据;
C、将共享内存上锁shareMemory.lock();
D、从共享内存中取数据;
E、使用完后将共享内存解锁shareMemory.unlock(),并将共享内存与进程分离shareMemory.detach();
*/int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);void *data = nullptr;const void *str = "好好学习,天天向上";//共享内存对象QSharedMemory shareMemory;//---------------写共享内存-----------------//1. 设置共享内存keyshareMemory.setKey("Kitty");//2. 判断进程是否与共享内存已经关联,如果已经关联就解除关联if (shareMemory.isAttached()){if (!shareMemory.detach()){qDebug() << shareMemory.errorString();return -1;}else{qDebug() << "共享内存关联成功";}}//3. 创建共享内存,同时关联共享内存if (shareMemory.create(1024)){qDebug() << "创建共享内存成功";}else{qDebug() << shareMemory.errorString();return -1;}//4. 将共享内存上锁shareMemory.lock();//5. 拷贝数据到共享内存data = shareMemory.data();if (nullptr == data){qDebug() << shareMemory.errorString();shareMemory.unlock();return -1;}memcpy(data, str, strlen(static_cast<const char *>(str)));//6.解锁共享内存if (!shareMemory.unlock()){qDebug() << shareMemory.errorString();return -1;}//---------------读共享内存-----------------//7. 将共享内存上锁shareMemory.lock();data = nullptr;//8. 拷贝数据data = shareMemory.data();qDebug() << static_cast<char *>(data);//9. 解锁共享内存if (!shareMemory.unlock()){qDebug() << shareMemory.errorString();return -1;}return 0;
}

执行结果

16:12:46: Starting D:\ProgramData\Qt\build-1TestShareMemrory-Desktop_Qt_5_15_2_MinGW_64_bit-Debug\
debug\1TestShareMemrory.exe ...
创建共享内存成功
好好学习,天天向上

06. 源码下载

下载:1TestShareMemrory.rar

07. 附录

7.1 Qt教程汇总
网址:https://dengjin.blog.csdn.net/article/details/115174639

【Qt】QSharedMemory类详解相关推荐

  1. Qt QImage类详解(QImage类型转换、QImage类函数及QImage像素操作)

    打开Qt帮助文档,会看到有关于QImage的描述如下:The QImage class provides a hardware-independent image representation tha ...

  2. QT QtableView操作详解

    本文实现了使用QtableView控件来显示数据,数据源使用txt文本作为数据源,使用了QStandardItemModel作为数据模型来实现了对TableView空间的初始化,和对txt数据源的增删 ...

  3. [QT] QMap使用详解

    [QT] QMap使用详解 引言 ​ QMap/QMultiMap属于关联式容器,其底层结构是通过二叉树实现,故其查找value的效率很快.QMap中的数据都是成对出现的,第一个称为key(键),第二 ...

  4. qstring如何初始化_学习QT之QString详解

    学习QT之QString详解 QString类保存16位Unicode值,提供了丰富的操作.查询和转换函数.该类还进行了使用隐式共享.高效的内存分配策略等多方面的优化. 一.字符串常用操作 字符串的操 ...

  5. OpenCV Mat类详解和用法(官网原文)

    参考文章:OpenCV Mat类详解和用法 我马克一下,日后更 官网原文链接:https://docs.opencv.org/3.2.0/d6/d6d/tutorial_mat_the_basic_i ...

  6. 转载:c+string类详解

    C++ string 类详解 </h1><div class="clear"></div><div class="postBod ...

  7. JDBC学习笔记02【ResultSet类详解、JDBC登录案例练习、PreparedStatement类详解】

    黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...

  8. JDBC学习笔记01【JDBC快速入门、JDBC各个类详解、JDBC之CRUD练习】

    黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...

  9. Android复习14【高级编程:推荐网址、抠图片上的某一角下来、Bitmap引起的OOM问题、三个绘图工具类详解、画线条、Canvas API详解(平移、旋转、缩放、倾斜)、矩阵详解】

    目   录 推荐网址 抠图片上的某一角下来 8.2.2 Bitmap引起的OOM问题 8.3.1 三个绘图工具类详解 画线条 8.3.16 Canvas API详解(Part 1) 1.transla ...

最新文章

  1. 全球智能驾驶公司列表
  2. 【北大微软】用于视频目标检测的记忆增强的全局-局部聚合
  3. vary渲染图没了_云渲染哪个好用?云渲染平台对比
  4. Win7环境下mysql报错1045:Access denied for user root@localhost错误解决方法
  5. 对团队建设与管理的几点看法
  6. 中国科学院大学计算机金智,金智-中国科学院大学-UCAS
  7. MySQL 5.0 新特性教程 触发器:第一讲
  8. c#开发Mongo笔记第五篇
  9. Windows 10 之修改登录背景(Win10BGChanger)
  10. 使用Julia进行图像处理--图像表示与匹配算法
  11. 广度搜索 -- 9.2 Word Ladder -- 求具体的路径 -- 图解
  12. 大年初一连夜带娃改bug:CTO把代码写成这鬼样子,被害惨了!
  13. JAVAWeb项目 微型商城项目-------(一)项目描述
  14. Android系统在新进程中启动自定义服务过程(startService)的原理分析
  15. matlab显示图片
  16. scratch制作彩虹猫病毒模拟器
  17. 延安日报20220323导读:“金斧”、金珠、玉刀、木箱
  18. MPC+HSM造就了安全的数字托管人
  19. OPenSSL漏洞原理与安全加固
  20. Epson me 打印机实现CorelDraw12中A4纸张无边距打印

热门文章

  1. 团队作业(五)——旅游行业的手机App
  2. 58同城买二手电脑的感想
  3. mysql 创建用户 create user_mysql创建用户并赋予用户权限详细操作教程
  4. android汉字笔顺数据库,Chinese stroke order app
  5. Java黑皮书课后题第5章:**5.37(十进制转二进制)编写程序,提示用户输入一个十进制整数,然后显示对应的二进制值(不要使用Integer.toBinaryString(int)方法)
  6. matlab system object,通过 System object 实现模块
  7. django ORM 操作
  8. MFC之COleVariant类
  9. C#学习笔记(集合)
  10. [转]Oracle DB 管理ASM实例