Linux进程间通信--共享内存

共享内存(Shared Memory)

共享内存就是允许多个不相关的进程访问同一个逻辑内存。 共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址。 而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。
在这里插入图片描述

共享内存是最快的进程间通信方式。但共享内存并没有提供同步互斥机制, 也就是说:当一个进程对共享内存的写操作结束前,并没有机制自动阻止另一个进程去读或写这块共享内存,这样就可能造成混乱。所以通常利用其他机制帮助共享内存实现同步,比如利用信号量机制。

1.通信原理

在Linux中,每个进程都有属于自己的进程控制块(PCB)和地址空间,并且都有一个与之对应的页表,负责将进程的虚拟地址与物理地址进行映射,通过内存管理单元进行管理。两个不同的虚拟地址通过页表映射到物理空间的同一区域,它们所指向的这块区域即共享内存。
在这里插入图片描述
当两个进程通过页表将虚拟地址映射到物理地址时,在物理地址中有一块共同的内存区,即共享内存,这块内存可以被两个进程同时看到。这样当一个进程修改共享内存的数据时,另一个进程访问共享内存时就会得到新的数据。

2.为什么共享内存通信最快?

因为共享内存是利用不同进程映射到同一块物理内存,不同进程对于共享内存的访问都是通过虚拟地址直接访问,没有涉及拷贝或复制问题, 而其他通信机制利用内核中的缓冲区,这就涉及到用户态和内核态之间的数据拷贝问题,拖慢了效率。所以共享内存最快。

3.特征&优缺点

特征:

  • 并无自带同步与互斥, 所以不安全, 需要用户自己控制。如:和信号量结合使用来达到进程间的同步及互斥
  • 生命周期随内核(共享内存不会随进程退出而销毁, 除非手动调用函数销毁)

优点 :

  • 传输速度快、效率高是最大的优点;
  • 共享内存对数据类型没有限制(不算优点的优点);
  • 通信方便 , 接口简单

缺点 :

  • 没有自带的同步互斥机制, 需要和信号量机制搭配使用, 让信号量来完成共享内存的同步互斥控制

4.共享内存的使用

ipcs //查看所有System V IPC

选项 :

  • -m 查看共享队列
  • -q 查看消息队列
  • -s 查看信号量

在这里插入图片描述
ipcrm 选项 id // 删除进程间通信资源

选项:

  • -m 删除共享队列
  • -q 删除消息队列
  • -s 删除信号量

5.共享内存操作流程

  1. 调用函数shmget()创建一个新共享内存段或者取得一个既有的共享内存段的标识符;
  2. 调用函数shmat()将共享内存附加到进程的虚拟地址空间中;
  3. 为了引用共享内存,程序需要使用由shmat()函数返回的addr值,它是一个指向进程的虚拟地址空间中该共享内存段起点的指针;
  4. 调用函数shmdt()分离共享内存段,调用之后,进程无法再引用这段共享内存。
  5. 调用函数shmctl()删除共享内存段。只有一个进程需要执行这一步。

共享内存在映射到各个进程的虚拟地址空间时,采用引用计数,映射一个进程的虚拟地址空间则加1,解除与一个进程的连接时则减1。 所以,当删除共享内存时,如果引用计数不为0,则不会马上删除,而是将这块共享内存的key值设置为0,表示这块共享内存不会再与任何进程发生连接(映射)。当这块共享内存的引用计数为0时,则释放。

6.操作共享内存的函数

创建共享内存:shmget()函数

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
  • 功能:创建共享内存或者取得一个既有的共享内存的标识符
  • 参数:

key: 程序需要提供一个参数key(非0整数),它有效地为共享内存段命名
key是标识共享内存的键值, (在IPC的通信模式下,不管是使用消息队列还是共享内存,甚至是信号量,每个IPC的对象都有唯一的名字,称为“键”)通过“键”,进程能够识别所用的对象。“键”与IPC对象的关系就如同文件名称之于文件,通过文件名,进程能够读写文件内的数据,甚至多个进程能够共用一个文件。而在IPC的通讯模式下,通过“键”的使用也使得一个IPC对象能为多个进程所共用。

size: 以字节为单位指定需要共享的内存容量,如果正在创建一个新段,则必须指定size。如果正在引用一个现存的段,则size指定为0.当创建一个新段,段内的内容初始化为0;

shmflg: 权限标志,它的作用与open函数的mode参数一样,如果要想在key标识的共享内存不存在时,创建它的话,可以与IPC_CREAT做或操作。共享内存的权限标志与文件的读写权限一样,举例:0644,它表示允许一个进程创建的共享内存被内存创建者所拥有的进程向共享内存读取和写入数据,同时其他用户创建的进程只能读取共享内存。

  • 返回值:成功返回与key相关的共享内存标识符(非负整数);失败返回-1

将共享内存映射到地址空间:shmat()函数

#include <sys/types.h>
#include <sys/shm.h>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值