首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >共享内存:进程通信速度之王

共享内存:进程通信速度之王

作者头像
用户11456817
发布2025-08-28 08:46:30
发布2025-08-28 08:46:30
11800
代码可运行
举报
文章被收录于专栏:学习学习
运行总次数:0
代码可运行

个人主页:Rhzkp-CSDN博客

Linux专栏:戎小半的Linux_Rhzkp的博客-CSDN博客


进程间通信标准:

  1. system V---共享内存
  2. linux内核支持了这种标准,专门设计了一个IPC通信模块,对于我们来说就是通信接口的设计

共享内存空间

共享内存是一种进程间通信的机制,即不同进程的虚拟内存空间(虚拟内存地址不需要相同),映射到相同的物理内存中。如果某个进程向共享内存写入数据,所做的改动将【立即影响到】【同时访问】(加了锁的就不算“同时可以访问")同一段共享内存的任何其他进程

在Linux中,每个进程都有属于自己的进程控制块(PCB)和地址空间(Addr Space),并且都有一个与之对应的页表,负责将进程的虚拟地址与物理地址进行映射,通过内存管理单元(MMU)进行管理。两个不同的虚拟地址通过页表映射到物理空间的同一区域,它们所指向的这块区域即共享内存

我们把将物理内存中的某段空间映射到多个进程的虚拟地址空间中的这种通信方式,叫做“共享内存”

在操作系统内,有多个共享内存同时存在,所以操作系统要将它们都管理起来

  • 先描述再组织
  • 共享内存一定会有对应的描述共享内存的内核结构。有这一点后,再加上物理内存。
  • 进程与共享内存的关系就是内核数据结构之间的关系。进程的内核数据结构与共享内存的数据结构

在共享内存中,存在引用计数,当引用计数为0时,表示没有进程在使用这块共享内存,此时就会被操作系统释放掉

共享内存是在用户空间还是内核空间?——用户空间

共享内存的接口,system V的特性

key:用来标识共享内存的唯一性

size:共享内存的大小

shmflg:共享内存创建的选项

怎么评估共享内存存在还是不存在?

怎么保证两个不同的进程,拿到的就是同一个内存?

  • 手动构建key
  • 查看一个已经创建的共享内存

ipcs -m

  • 删除共享内存

ipcrm -m +共享内存id

能不能使用key来代替id?

不能。为什么?

key是要给内核进行区分唯一性的。用户使用指令管理共享内存是在用户层的,而指令内部是对系统调用进行了封装的。也就是说,指令是运行在用户层的,而key是给OS用的,所以不能使用key来代替id

  • 代码删除共享内存
代码语言:javascript
代码运行次数:0
运行
复制
 void Destroy()
    {
        if(_shmid == gdefaultid)return;
        int n=shmctl(_shmid,IPC_RMID,nullptr);
        if(n > 0)
        {
            printf("shmctl delete shm: %d success!\n",_shmid);
        }
        else
        {
            EXR_EXIT("shmctl\n");
        }
    }   
共享内存的生命周期
  • 共享内存的生命周期随内核。
  • 如果进程没有显示的删除对应的共享内存,即便进程退出了,ipc资源依旧被占用
如何使用共享内存

使用共享内存需要先把共享内存映射到进程的地址空间当中。

怎么映射的?

操作系统提供了一个系统调用shmat。调用这个系统调用的进程会把自己的堆栈之间的映射区和队友的共享内存建立映射。

成功:返回共享内存起始的虚拟地址

失败:-1

shmat,将共享内存挂接到进程的地址空间中

共享内存的权限

共享区属于用户空间

共享内存是进程间通信中,速度最快的方式:
  1. 两个进程都映射了这块空间,映射之后读写直接被对方看到
  2. 不需要进行系统调用进行读取或者写入内容,直接以指针地址的方式访问空间
共享内存的缺点:
  1. 通信双方没有所谓的同步机制
  2. 因为没有同步机制,所以会导致数据不一致

共享内存没有保护机制

消息队列

消息队列和共享内存都属于system V标准

创建消息队列:

system V信号量

铺垫:

共享内存:

让两个进程看到同一份资源来实现通信:

  • 让两个进程看到同一份资源这是提供了通信前提
  • 如果共享内存没有保护机制,会导致数据不一致

数据不一致的解决方案

  • 信号量

保护机制保护的是谁?或者说约束的是谁?

  • 临界区代码
  • 保护临界区代码就是变相的保护临界资源

什么是临界区?

其实就是访问共享内存的代码段,这部分就是临界区

为什么会数据不一致?

  • 存在没有被保护的共享资源
  • 各自的代码,访问了这个没有被保护的公共资源
  1. 多个执行流(进程)能看到的同一份公共资源:共享资源
  2. 被保护起来的共享资源叫做“临界资源”
  3. 在进程中,涉及到互斥资源的程序段叫做临界区---即访问该资源的代码段
  4. 多个执行流访问资源时,具有一定顺序性,叫做同步

什么是互斥

任何时刻,只允许一个执行流访问资源,叫做互斥

在申请锁的时候,必须是原子的

没当一个执行流进入临界区时,就会申请锁,这说明锁本身也是共享的

那么谁来保证锁的安全?

  • 申请锁的时候,必须是原子的

对共享资源进行保护实际上是对访问共享资源的代码进行保护

原子性是什么?

  • 要么做,要么不做

信号灯,本质是一个计数器,用来表明临界资源中,资源数量的多少

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 共享内存空间
    • 共享内存是在用户空间还是内核空间?——用户空间
    • 共享内存的生命周期
    • 如何使用共享内存
    • 共享内存的权限
    • 共享内存是进程间通信中,速度最快的方式:
    • 共享内存的缺点:
  • 消息队列
  • system V信号量
    • 什么是互斥
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档