LINUX/进程通信:共享内存/消息队列/信号量

本文深入探讨了共享内存作为进程间通信方式的工作原理,包括其创建、映射、操作及释放流程,对比了共享内存与管道通信的效率,并介绍了消息队列和信号量在进程通信中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

共享内存

共享内存:是在物理内存上开辟一块空间,需要通信的进程通过页表映射这块物理内存地址到各自的虚拟地址空间上,进而可以通过虚拟地址空间访问这块空间,实现数据共享。
在这里插入图片描述
特性:共享内存是最快的进程通信方式
管道通信:这种通信方式,涉及两次用户态与内核态之间的拷贝,将数据写入管道,再从管道中读取数据。
共享内存:直接通过虚拟地址访问物理内存实现对共享内存中数据的操作,相比与管道通信少了两次用户态与内核态之间的数据拷贝,因此速度最快。

共享内存的操作流程:
1.创建共享内存---在物理内存上开辟空间
2.进程将共享内存映射到自己的虚拟地址空间
3.基本的内存操作都可以对这块空间进行操作
4.解除虚拟地址与共享内存之间的映射关系
5.释放共享内存资源

具体实现:
1.创建共享内存

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

key:内核中共享内存的标识符,不同进程通过这个标识符才能找到共享内存,用户可自己定义

#define IPC_KEY 0x12345678

size:共享内存的大小—内存以页为单位(4kb/页)
shmflag:IPC_CREAT存在则打开不存在则创建,与内核IO的flag基本相似
返回值:一个非负整数----共享内存的操作句柄,创建失败返回-1

2.映射

void *shmat(int shmid,const void* shmaddr,int shmflag)

shmid:共享内存的操作句柄
shmaddr:映射到的虚拟地址的首地址,一般置NULL,通过系统自己映射。
shmflg: SHM_RDONLY读操作/0 默认可读可写

3.解除映射关系

int shmdt(const void* shmaddr)

shmaddr:映射到的虚拟地址的首地址

4.释放共享内存资源

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

shmid:共享内存的操作句柄
cmd:对共享内存的操作,IPC_RMID–删除共享内存
shm_id*buf:查看/设置共享内存信息的结构,不用则置NULL

:共享内存并不是立刻被删除,而是先将状态置为销毁状态,删除标识符----为了不让这个共享内存被其他进程继续映射连接,当共享内存与进程连接数为0时,才会真正销毁这块共享内存

操作系统中查看共享内存的指令:
ipcs:查看进程间通信资源
-m查看共享内存
-q查看消息队列
-s查看信号量
ipcrm -m :删除进程间通信资源

特性:
①共享内存是最快的进程通信方式
管道通信:这种通信方式,涉及两次用户态与内核态之间的拷贝,将数据写入管道,再从管道中读取数据。
共享内存:直接通过虚拟地址访问物理内存实现对共享内存中数据的操作,相比与管道通信少了两次用户态与内核态之间的数据拷贝,因此速度最快。
②生命周期随内核
③共享内存并没有自带同步与互斥(多个进程访问时存在安全问题)
④共享内存的数据写入是一种针对地址指向空间的覆盖式写入。

消息队列

内核中的一个优先级队列,进程通过访问同一个队列,向队列中添加结点或者获取结点实现通信

消息队列的操作:
1.创建消息队列—内核中的一个优先级队列
2.进程向同一个队列中添加/获取结点
3.删除消息队列

特性:
1.自带同步与互斥
2.生命周期随内核

信号量

本质上是一个程序计数器+进程等待队列
用于实现进程通信的同步与互斥(共享内存不带同步与互斥,多个进程操作缺乏安全性,因此需要信号量来保护对共享内存的操作)
同步通过条件判断来实现对临界资源访问的合理性
互斥通过唯一访问来实现对临界资源访问的安全性

信号量的计数器用来对内核中的资源进行计数,每当有进程访问需要资源时,先通过计数判断资源是否够进程使用:

①计数>0,可以访问,获取一个资源,计数-1;
②计数<=0,不可以访问,没有可获取资源,计数-1,进程进入等待队列,状态置为可中断睡眠状态
③当其他进程释放了资源后,计数+1,此时若计数>0,则什么都不干,若计数<0;则从等待队列中唤醒一个进程去获取资源

同步的实现:有资源可以访问的时候访问,没有资源的时候进行等待。
信号量通过自身的计数器+等待队列,以及让进程进行等待与唤醒进程操作实现。

互斥的实现:保证同一时间只能有一个进程进行资源的访问
通过让信号量的计数器不大于1,以及只有一份资源可访问实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值