alin的学习之路:共享内存

1. 概念

共享内存是进程间通信中效率最高的一种方式。

  • 共享内存: 可以被多个进程同时使用的一块内核的内存

    • 有血缘关系的进程
    • 没有血缘关系的进程
    • 这块内存不属于任何的进程, 属于内核 -> 内核对应的在物理内存上的存储空间
  • 共享内存的作用:
    • 进程间通信
    • 进程间通信的方式:
      • 管道(匿名, 有名)
      • 内存映射区 -> 这内存位于进程地址空间用户区的动态库加载区
        • 内存映射区中的内存是属于某个进程的
      • 信号 -> 不推荐使用
      • 套接字
        • 本地套接字(本地的进程间通信)
        • 网络套接字(本地/非本地的进程间通信)
    • 共享内存是迄今为止接触的进程间通信中效率最高的一种

2. 共享内存的使用步骤

  • 共享内存不存在时
  1. 基于一个key来创建共享内存,在Linux下 key是一个整数,在Windows下 key是一个字符串。创建出来的共享内存不属于任何进程,属于内核
  2. 如果某个进程想要使用这块内存,需要与这块内存进行关联
    • 调用相关函数
  3. 如果关联成功,则会获得共享的起始地址,根据这个地址读/写数据
  4. 读写数据前需要加锁,结束后需要解锁
  5. 如果不需要再使用这块共享内存了,可以和共享内存解除关联
    • 调用相关函数即可
    • 解除关联之后,共享内存依然存在,只是这个进程和该共享内存没有关系了
    • 如果进程没有解除关联就退出了,那么会自动解除关联
    • 如果说当前有n个进程和共享内存进行了关联, 这时候删除共享内存, 共享内存依然存在
      • 共享内存的内部维护了一个引用计数 (和共享内存关联的进程的个数)
      • 当引用计数>0的时候, 对共享内存做了删除操作, 共享内存不会被销毁, 当应用计数==0的时候就自动被销毁了(之前的删除操作现在才起作用)
      • 当引用计数==0的时候删除共享内存, 共享内存马上被释放
  • 当共享内存已经存在了
  1. 通过已经创建好了的共享内存的key来打开这块内存
  2. 和共享内存进行关联
  3. 基于起始地址读写内存
  4. 和共享内存解除关联

3. Qt中的共享内存:QShareMemory

下边的是Qt将系统的共享内存API封装之后的得到的类

  • 在Qt框架中为了避免内存泄露, 在Qt中使用共享内存的时候, 如果创建共享内存的对象被释放了, 这块共享内存也就没有了
  • 如果在程序中对共享内存进行解除关联的操作, 共享内存也就被释放了
// 构造函数
QSharedMemory::QSharedMemory(const QString &key, QObject *parent = Q_NULLPTR);
参数:- key: 共享内存的唯一标识, 通过这个key来创建/查找共享内存- parent: 指定父对象
QSharedMemory::QSharedMemory(QObject *parent = Q_NULLPTR);
// 给共享内存对象指定 key 值
void QSharedMemory::setKey(const QString &key);// 创建共享内存, 创建成功之后, 进程就自动和共享内存关联到一起了
// 如果基于某个key的共享内存已经存在了, 再调用create函数, 返回false
bool QSharedMemory::create(int size, AccessMode mode = ReadWrite);
参数:- size: 共享内存的大小, 单位: 字节- mode: 对共享内存的访问权限, 默认是读写- QSharedMemory::ReadOnly- QSharedMemory::ReadWrite
返回值:- 成功: true- 失败: false// 和共享内存进行关联
// 关联成功之后, 默认的访问权限也是读写
bool QSharedMemory::attach(AccessMode mode = ReadWrite);
参数:- mode: 对共享内存的访问权限, 默认是读写- QSharedMemory::ReadOnly- QSharedMemory::ReadWrite
返回值:- 成功: true- 失败: false// 判断当前进程是否和共享内存关联到一起了
bool QSharedMemory::isAttached() const;
返回值:- 已经关联了: true- 没有关联: false// 得到共享的起始地址, 必须要关联成功
// 如果进程没有和共享内存进行关联, 调用这个函数返回NULL
void *QSharedMemory::data();    // -- 用的比较多, 默认情况下对共享内存的权限是: 读写
const void *QSharedMemory::data() const;
const void *QSharedMemory::constData() const;// 对共享内存加锁
bool QSharedMemory::lock();// 对共享内存解锁
bool QSharedMemory::unlock();// 和共享内存解除关联
bool QSharedMemory::detach();// 打印共享内存操作失败的原因
QString QSharedMemory::errorString() const;// 得到共享内存对象关联 key 字符串
QString QSharedMemory::key() const;// 得到关联的共享内存的大小
int QSharedMemory::size() const;
返回值:- 如果成功关联了共享内存: 共享内存的大小- 没有关联共享内存: 0

4. 读写内存在Qt中的demo

struct Person
{int num;char name[24];
};

ReadShm

QSharedMemory* shm = new QSharedMemory(this);
shm->setKey("123456");
shm->attach();shm->lock();
Person* pAddr = (Person*)shm->data();
qDebug() << "num = " << pAddr->num<< "name = " << pAddr->name;
shm->unlock();shm->detach();

WriteShm

QSharedMemory* shm = new QSharedMemory("123456");
shm->create(1024);
bool bl = shm->create(1024);
if(!bl)
{qDebug() << "shm->create(1024) error: " << shm->errorString();return;
}Person* pAddr = (Person*)shm->data();
shm->lock();
pAddr->num = 100;
strcpy(pAddr->name, "alin");
shm->unlock();

alin的学习之路:共享内存相关推荐

  1. alin的学习之路:设计模式之单例模式

    alin的学习之路:设计模式之单例模式 单例模式,顾名思义就是类只有一个实例对象,并且她自己负责创建自己的对象,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象. 单例模式 ...

  2. alin的学习之路:序列化与protobuf

    alin的学习之路:序列化与protobuf 1. 序列化(串行化) 序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程,与之相对应的过程称之为反序列化(Unser ...

  3. alin的学习之路:面试题 数据库相关

    alin的学习之路:面试题 数据库相关 如何提高查询速度? 使用索引 create index 索引名 on 表名(列名1,列名2,--); 数据库索引,事务,事务级别 使用索引可以提高查询效率 事务 ...

  4. alin的学习之路:加密相关知识(加密和解密,常见加密算法,消息验证码HMAC,数字签名)

    alin的学习之路:加密相关知识(加密和解密,常见加密算法,消息验证码HMAC,数字签名) 1. 加密和解密 1.1 加密的三要素 原始数据 加密操作: 明文 -> 密文 解密操作: 密文 -& ...

  5. alin的学习之路(数据库篇:三)(多表查询,子查询,集合运算,数据处理)

    alin的学习之路(数据库篇:三)(多表查询,子查询,集合运算,数据处理) 1. 多表查询 1.1 笛卡儿积 笛卡尔积就是两个集合的乘积计算 . 如果多个表进行联合查询, 得到结果是一个笛卡尔积, 举 ...

  6. alin的学习之路(数据库篇:五)(MySQL的相关语句及API的C语言实现)

    alin的学习之路(数据库篇:五)(MySQL的相关语句及API的C语言实现) 1. MySQL概述与登陆MySQL mysql 与 oracle 的区别 oracle 是一个数据库实例下有多个用户, ...

  7. alin的学习之路(Linux系统编程:五)(目录操作、进程相关概念)

    alin的学习之路(Linux系统编程:五)(目录操作.进程相关概念) 1. 目录操作 1. 查看工作目录 getcwd char *getcwd(char *buf, size_t size) 功能 ...

  8. alin的学习之路(Linux系统编程:一)(Linux基础命令)

    alin的学习之路(Linux系统编程:一)(Linux基础命令) 1.Linux学习准备 操作系统的作用 向上给用户提供简单的操作计算机硬件的方式 对下管理硬件 承上启下 程序运行在操作系统上,程序 ...

  9. alin的学习之路(Linux系统编程:三)(vim,gcc,库,gdb)

    alin的学习之路(Linux系统编程:三)(vim,gcc,库,gdb) 1.vim的使用 vim有三种模式:命令模式,末行模式,编辑模式 光标的移动[命令模式] h 向左 ,j 向下,k 向上,l ...

最新文章

  1. msiexec 命令使用文档
  2. 编写高质量代码:改善Java程序的151个建议(第1章:JAVA开发中通用的方法和准则___建议1~5)...
  3. Spring RestTemplate中几种常见的请求方式GET请求 POST请求 PUT请求 DELETE请求
  4. 前端学习(2306):react之组件使用
  5. Android应用程序结构总结
  6. linux培训课程第十三天:ppt以及笔记
  7. 双光子荧光成像_在不影响分辨率的情况下,成功将双光子显微镜成像速度提高5倍!...
  8. linux cat 重定向,Linux命令(cp mv cat和重定向)(示例代码)
  9. 深度学习之RNN、LSTM、GRU篇
  10. File类和时间类的两道综合练习
  11. python settings_python settings如何配置sqlite?
  12. Intellij idea注册激活码(2017年2月15日亲测可用于最新版)
  13. golang 时间格式转换汇总
  14. 慎用yum update
  15. Perl之Spreadsheet::WriteExcel
  16. 微信小程序预览 word、excel、ppt、pdf 等文件
  17. 【HAL库】HAL库STM32cubemx快速使用
  18. ui设计能干一辈子吗
  19. 什么是vps?vps和代理ip的本质区别?
  20. 2012年一个屌丝程序员的学习总结:读书、户外、泡妞、习惯、母猪产后护理...

热门文章

  1. 【UGUI】如何实现自动滚动文本效果
  2. [其他] 看记录片编辑室《十五岁的中学生》有感
  3. Arduino小白学习记录:双色LED灯实验
  4. 急!急!急!有偿求助
  5. Runas命令:能让域用户/普通User用户以管理员身份运行指定程序
  6. 自定义ComboBox控件,完美解决C#自带的ComboBox效率慢的问题
  7. Scrapy模块爬取中华英才网招聘信息(分页)
  8. MATLAB机器人寻找轨迹路线规划源代码
  9. 实战!手把手带你复现1篇视频分类顶会论文
  10. 程序人生-感受湖光景色随笔