Linux进程间通信 共享内存+信号量+简单例子

每一个进程都有着自己独立的地址空间,比如程序之前申请了一块内存,当调用fork函数之后,父进程和子进程所使用的是不同的内存。因此进程间的通信,不像线程间通信那么简单。但是共享内存编程接口可以让一个进程使用一个公共的内存区段,这样我们便能轻易的实现进程间的通信了(当然对于此内存区段的访问还是要控制好的)。

共享内存实现进程通信的优点:

共享内存是进程通信方式中最快速的方式之一,它的快速体现在,为数据共享而进行的复制非常少。这里举例来说,使用消息队列时,一个进程向消息队列写入消息时,这里有一次数据的复制,从用户空间到内核空间。而另一个进程读取消息的时候,又有一次数据的复制,从内核空间到用户空间,这无疑是耗费时间与资源的。然而共享内存的存在则无需这两次复制,进程是从它们各自的地址空间直接访问共享的内存区段的。

缺点:

还是拿消息队列来对比,消息队列已经实现了对自身读写的保护,然而共享内存需要我们开发者自己来实现,这无疑增加了开发的难度


下面我们还是沿袭之前的风格,先简要介绍GNU/LINUX中提供哪些关于共享内存的编程接口,再以一个简单的小例子收尾。

#include<sys/shm,h>


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

该函数用于创建一个新的共享内存区段,或者是获取一个已经存在的共享内存区段

返回一个id(描述符),该id唯一表示系统中创建的这段内存

key可以是一个非0的值,也可以指定为IPC_PRIVATE,跟信号量一样,IPC_PRIVATE指明创建的是一个私有的内存区段,这样的话其它进程无法找到它,通常在仅需要一个进程组

的内部进行访问时,会使用这种方法。

size是创建的内存区段的大小,因为内存区段是创建在内存页面上的,它的容量上限通常为4MB,视实际环境决定。

flag,该参数通常是由两部分组成,一部分是访问权限,一部分是指令。指定具有三种情况,一种是创建一个共享内存区段,那么设置为IPC_CREAT即可,如果该内存区段以存在时我们需要返回一个错误的话,那么传入IPC_CREAT|IPC_EXCL,在已经存在的情况下,会返回一个错误,并且将errno置为EEXIST.第三种是获取已经存在的内存区段,那么传入0即可。关于权限,一般情况下我们设置0666或者0600就行了,它的具体值和意义如下所示:

0400   用户拥有读取权限

0200   用户拥有写入权限

0040   用户组拥有读取权限

0020   用户组拥有写入权限


0004   其他用户拥有读取权限

0002   其他用户拥有写入权限


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

操作成功返回0,否则返回错误值

shmid,要操作的共享内存区段的描述符

cmd,要进行操作的指令

shmid_ds 用于获取共享内存数据结构体,该结构体里存储关于该段内存的所有信息,这里不细说了,大家可以百度了解一下。

该函数通常是用于完成三个功能,一是cmd为IPC_STAT,读取当前的共享内存数据结构体,二是cmd为IPC_SET,用于写入共享内存结构体。三是传入IPC_RMID,用于移除该段内存

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

返回值是共享内存地址映射在该进程内存地址的起始地址,为-1时,挂接失败。

shmid,共享内存的描述符

shmaddr,指定共享内存地址映射在进程内存地址的什么位置,置为NULL时,让内核自己决定。

flag,如果为SHM_READONLY,那么在调用进程中将以只读方式挂接内存区段,传入0时(不指定时)将以可读写方式挂接。

int shmdt(void* shmaddr)

该函数作用是脱离内存区段,取消从共享内存区段想进程的局部空间的映射,从而也释放了为了挂接区段而占用的局部空间地址。成功返回0,失败返回-1.

shmaddr,是调用shmat时返回的进程空间地址(也就是共享内存地址映射在进程空间的地址)


共享内存的基本操作介绍完了,在文章开头提到过,共享内存需要我们进行读写控制,这里我采用信号量,(如果对于信号量不清楚的,可以去看我之前写的一篇文章

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值