Linux IPC:共享内存_linux创建共享内存ipc_excl-程序员宅基地

技术标签: Linux  进程间通信  linux  共享内存  IPC  

  本文介绍另一种进程间通信方式:共享内存。

一、共享内存的理解

什么是共享内存?

  共享内存就是申请了一块物理内存用来进行数据共享,需要进行数据共享的进程可以将同一块物理内存映射到自己的虚拟地址空间,然后通过自己的虚拟地址空间直接访问这块空间,从而实现数据交流。

共享内存和管道的区别:

 (1)管道的通信类型是传输,数据是先进先出的,数据被读取走之后才会消失,因此数据不会被覆盖

 (2)共享内存是覆盖式的,因此如果多个进程对共享内存进行操作的话,就会存在安全隐患。但是共享内存也是最快的进程间通信方式。

共享内存与管道在数据传输效率中的差异:

 (1)管道:数据在传输过程中经历了两次数据在内核空间与用户空间之间的拷贝

 (2)共享内存:进程直接通过虚拟地址空间访问共享内存,不需要进行内核空间与用户空间的两次数据拷贝

  如图:进程A和进程B之间如果使用管道进行数据传输,那么首先进程A要把数据从用户空间拷贝一份发送到内核空间的管道中。然后进程B要从内核空间中拷贝一份数据到用户空间中,这样才可以使用。因此管道传输一次数据要经历两次在内核空间与用户空间之间的拷贝。

管道

  如图:共享内存是在物理内存中申请的一块空间,需要共享数据的两个进程都与这块共享内存建立映射关系,然后就可以直接从共享内存中读取数据,而不需要经历两次拷贝,因此是最快的进程间通信方式。

共享内存传输方式

二、共享内存操作流程

  1. 创建或打开共享内存:

    • 创建共享内存就是开辟一块物理内存用来作为共享内存,打开共享内存就是打开已经被开辟好的共享内存。
  2. 将共享内存映射到虚拟地址空间:

    • 进程要想使用这块共享内存,就必须让共享内存映射到进程的虚拟地址空间,这样进程就可以通过虚拟地址空间访问这块共享内存。
  3. 共享内存操作:

    • 操作共享内存就是使用共享内存进行通信,也就是将数据写入到共享内存或者从共享内存中读取数据等操作。
  4. 解除映射关系

    • 在共享内存使用完毕后,需要先解除共享内存与进程虚拟空间的映射关系。
  5. 删除共享内存

    • 解除映射关系后就可以删除共享内存。

  在删除共享内存的时候,还有一个东西要注意:映射连接数和这块共享内存建立映射的进程的个数)。

  进程解除和共享内存的映射关系后,映射连接数减1。但是一个共享内存通常是多个进程一起操作的(比如进程A,进程B),进程A执行了删除共享内存的操作后,这个共享内存是不会被立即删除的,不然进程B用的好好的突然断了咋整。

  因此执行了删除共享内存这操作后,共享内存不能被立即删除,但是共享内存会被标记成被删除的状态,以后其他进程如果要连接这个共享内存,系统发现该共享内存是被删除状态,就拒绝其他进程连接了。

  等到连接这块共享内存的进程都和这块共享内存解除映射后,映射连接数就变成了0,此时系统才会释放共享内存。

三、共享内存操作接口

 按照共享内存的操作流程来依次介绍共享内存的操作接口。

1.创建/打开共享内存

int shmget(key_t key,size_t size,int shmflag)

 作用:创建或打开共享内存

  • ket_t key:共享内存的标识符,也就是共享内存的名字(注意把标识符和文件标识符区分开)。

  • size_t size:要创建的共享内存的大小。

  • int shmflag:创建权限/打开方式。如果是创建共享内存就是创建权限,如果是打开共享内存就是打开方式。打开方式通常是 IPC_CREAT(共享内存不存在就创建)

 返回值:成功返回共享内存的操作句柄(非负整数),失败返回-1

关于key:
  多个进程通过共享内存的名字找到同一个共享内存。(如果把名字命名为 IPC_PRIVATE,就代表这个共享内存只能用于具有亲缘关系的进程间通信,因为这样其他进程就找不到这个共享内存)

关于size:
  共享内存的大小和共享内存的占用空间不是一回事。共享内存空间的开辟是以内存页为单位的,不是说要创建10字节的共享内存就会开辟10字节大小的共享内存空间。因为内存和磁盘的空间管理是以块为单位管理的,而不是以字节为单位管理。

  也就是说,如果要创建10字节的大小的共享内存,实际上会开辟4096个字节大小的共享内存,只不过使用的大小是10字节。

2.进程与共享内存建立映射关系

void* shmat(int shmid,void* addr,int shmflag)

 作用:建立映射关系

  • shmid:要建立映射的共享内存的操作句柄。
  • addr:指定映射首地址,也就是把共享内存映射到虚拟空间的什么位置,通常置NULL(让系统自己选择合适的位置)。
  • shmflag:要对共享内存进行的操作,通常传入0(可读可写),也可以是SHM_RDONLY(只读)

 返回值:建立成功则返回映射的空间的首地址(通过这个地址操作共享内存),失败返回(void*)-1。

映射位置

3.操作共享内存

  因为共享内存其实就是一块内存,因此我们可以直接用操作内存的函数来操作共享内存,比如:memcpy、strcpy、printf

4.进程解除与共享内存的映射

int shmdt(void* shm_start)

 作用:解除进程与指定的共享内存的映射关系

  • shm_start:共享内存在虚拟空间中的映射首地址。

5.删除共享内存

int shmctl(int shmid,int cmd,struct shmid_ds* buf)

 作用:删除共享内存(这个函数不止是用来删除,它的功能很多,只不过我们常用到的是删除功能)

  • int shmid:要操作的共享内存的操作句柄。
  • int cmd:要对共享内存进行的操作。 我们通常使用 IPC_RMID(表示删除共享内存)
  • struct shmid_ds* buf:用于设置或者获取共享内存信息,不用则置NULL。

 返回值:返回值其实不是固定的,因为不同的操作选项代表了不同的功能,不同的功能有不同的返回值。对于删除操作来说,成功返回0,失败返回-1。

四、共享内存相关指令

1.查看共享内存信息

  • ipcs -m

 如图:此时系统中只有一个共享内存。

  • key:共享内存的名字
  • shmid:共享内存的id
  • owner:共享内存的拥有者
  • perms:权限
  • bytes:共享内存大小
  • nattch:映射连接数
  • status:共享内存的状态

查看共享内存的信息

2.删除指定共享内存

  • ipcrm -m shmid

  注意,此时的共享内存状态改变为 dest(被删除状态),变成这个状态后就不允许其他进程再和它建立映射了。

删除共享内存

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_57761086/article/details/127868002

智能推荐

Unity手机震动,Unity -> ios 震动_unity nice vibrations-程序员宅基地

文章浏览阅读2.1k次。说明Unity 有自己的 接口 Handheld.Vibrate() 来实现手机的震动,这里来介绍下Unity调用ios原生震动。原生ios实现脚本下面有2个脚本都是震动的实现,用来自己测试。iOSHapticInterface.m与MultiHaptic.mm脚本。建议使用iOSHapticInterface.m脚本。iOSHapticInterface.m// This iOS haptic interface is a pretty straightforward impleme_unity nice vibrations

C语言中关于while语句的理解以及getchar和putchar_include<stdio.h>int main(){while(putchar(getchar()-程序员宅基地

文章浏览阅读888次,点赞32次,收藏9次。continue:跳过本次continue循环后面的代码,重新去判断部分(也就是重新进入while循环),看是否能够进行下一次循环。这串代码与上一次相比,我们把while中的条件改为了i_includeint main(){while(putchar(getchar())!='?'); return 0;}

74hc164驱动数码管c语言程序,74hc164应用电路图_74hc164驱动源程序-程序员宅基地

文章浏览阅读3.3k次。74hc164是高速硅门 CMOS 器件,与低功耗肖特基型 TTL (LSTTL) 器件的引脚兼容。74hc164是 8 位边沿触发式移位寄存器,串行输入数据,然后并行输出。数据通过两个输入端(DSA 或 DSB)之一串行输入;任一输入端可以用作高电平使能端,控制另一输入端的数据输入。两个输入端或者连接在一起,或者把不用的输入端接高电平,一定不要悬空。时钟 (CP) 每次由低变高时,数据右移一位,..._74hc164数码管

pyinstaller centos 打包记录_centos pyinstall-程序员宅基地

文章浏览阅读178次。报错2:error while loading shared libraries: libpython3.7m.so.1.0: cannot open shared object file: No such。报错1:OSError: Python library not found: libpython3.7mu.so.1.0, libpython3.7.so, l。添加库的配置信息,将python/lib的绝对路径(一般为:’/usr/python/lib’),添加至conf文件中。_centos pyinstall

linux下统计log中某个时间段的内出现某个关键字保存到文件_linux命令统计某个时间区间出现的关键字-程序员宅基地

文章浏览阅读674次。1、查看图中两个时间段内,且有“统计存储图片数据”的字段的日志 sed -n '/2021-06-03 11::25:34/,/2021-06-03 11:26:02/p' start.log |grep "统计存储图片数据" 注释: -n参数:只有经过sed特殊处理的那一行(或者动作)才会被显示 p参数:表示在终端打印出来 start.log:日志文件 grep: 对前面查询的结果进行过滤 "统计存储图片数据": 查询的关键字 时间段:格式和日志保持一致,且时间值是真实存在的2、将时._linux命令统计某个时间区间出现的关键字

手机翻译html工具,1分钟教你用手机实时翻译,自带翻译功能就是强大,各牌手机均可...-程序员宅基地

文章浏览阅读2.6k次。手机现在已经是我们的随身物品了,在很多事情上手机都可以帮助到我们,比如翻译,现在不仅是出国会用到翻译,就想平时的自我学习和工作上,都会遇到翻译的情况,今天就教大家一招用手机直接翻译的方法!今天主要就是给大家揭秘不同品牌手机里的翻译功能,一起来看看吧!1.小米手机小米手机在国产手机里的是非常受欢迎的,小米手机里的【扫一扫】不知道大家用过没有,我们打开扫一扫点击【翻译】然后选择翻译前后的语言,最后点击..._html格式的网页进行翻译

随便推点

使用Ajax实现简单的增删查改&&前端Ajax传的值,后端如何获取_ajax增删改查-程序员宅基地

文章浏览阅读4k次,点赞3次,收藏40次。实现查询和增删改一、Ajax最基本语法二、增删查改1.查询(Get请求)2.增删改(Post请求)三、后台(MVC/WebForm)1.MVC(Post请求)2.WebForm(Post请求)本人小白一个。其中所说可能有些不足,因为这些是我自己在写项目的过程中所使用的Ajax如有不对的地方,欢迎评论提出建议。一、Ajax最基本语法话不多说,直接上代码$.ajax({ url: "/User/GetUser",(这里写请求路径) type: "g_ajax增删改查

m4s格式转换mp4怎么转?只需3个步骤~-程序员宅基地

文章浏览阅读894次,点赞8次,收藏6次。无论您使用的是Windows、Mac还是Linux系统,主流播放器如VLC、Windows Media Player、QuickTime等都能轻松打开MP4文件,确保用户能够在各种平台上畅快观影。如果需要将M4S转换成MP4,野葱视频转换器为我们提供了便捷的解决方案,不仅具有稳定性,极少发生文件损坏,而且转换速度快,大大节约了时间。随着网络视频的普及,M4S通过分片存储音频和视频数据,提高了网络传输的效率,使得用户在观看视频时能够更加流畅地体验。处理完成后,你将在指定的输出路径中找到生成的MP4文件。_m4s格式转换mp4

CAN协议_为什么can诊断都是7开头-程序员宅基地

文章浏览阅读596次。网络管理报文(CAN 4开头,CAN FD 5开头),应用报文,诊断报文(7开头,物理寻址:一对一 比如对单体安全访问,在线编程,功能寻址:服务需要一对多,保证ECU的状态相同,比如多个 ECU需要知道车速的信息,温度的信息)CAN_H的电平为3.5V,CAN_L线的电平为1.5V,CAN_H和CAN_L的电压差为2V左右,CAN_H和CAN_L线上的电压均为2.5v, CAN_H和CAN_L之间的电压差为0V。1、位错误:当总线赢得发送权后,会对总线电平进行侦听,当发送的电平和侦听的电平不一致;_为什么can诊断都是7开头

基于OPC自定义接口的OPCClient功能改进_titaniumas.opc.client-程序员宅基地

文章浏览阅读2.7k次,点赞2次,收藏9次。在本人之前的一篇博文中描写了如何使用OPC自定义接口开发OPCClient,并使用SignalR实现数据的远程实时传输。融合SignalR的OPCClient实现环境参数实时监测但是在使用过程中发现仍有不足之处,本文就是对之前OPCClient的功能改进进行说明。1.问题描述原有的OPCClient在测试环境下可以正常运行,但是在实际生产环境下长时间运行后问题就逐渐暴露出来。主要的问..._titaniumas.opc.client

宏工科技十五周年,“归零心态”竞逐全球-程序员宅基地

文章浏览阅读75次。宏工科技十五周年,“归零心态”竞逐全球

c++中的extern “C“_c++ extern c-程序员宅基地

文章浏览阅读1.6k次。c++中的extern "C"_c++ extern c

推荐文章

热门文章

相关标签