进程间共享内存(一)

原文链接:共享内存

System V进程间通信(IPC)包括3种机制:消息队列,信号量,共享内存。

消息队列和信号量均是内核空间的系统对象,经由它们的数据需要在内核和用户空间进行额外的数据拷贝;而共享内存和访问它的所有应用程序均同处于用户空间,应用进程可以通过地址映射的方式直接读写内存,从而获得非常高的通信效率。

System V为共享内存定义了下列API接口函数:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

key_t ftok(const char *pathname,int proj_id);
int shmget(key_t key,int size,int shmflg);
void *shamat(int shmid,const void *shmaddr, int shmflg);
int shmdt(void *shmaddr);
int shmctl(int shmid,int cmd,struct shmid_ds *buf);

ftok :函数用于声称一个键值:key_t key,该键值将作为共享内存对象的唯一性标识符,并提供给为shmget函数作为其输入参数;ftok函数的输入参数包括一个文件(或目录)路径名:pathname,以及一个额外的数字:proj_id,其中pathname所指定的文件(或目录)要求必须已经存在,且proj_id不可为0;


shmget :函数用于创建(或者获取)一个由key键值指定的共享内存对象,返回该对象的系统标识符:shmid;


shmat :函数用于建立调用进程与由标识符shmid指定的共享内存对象之间的连接;


shmdt :函数用于分离调用进程与共享内存对象之间的连接;


shmctl :函数用于对已创建的共享内存对象进行查询,设值,删除等操作。


ftok的陷阱

根据pathname指定的文件(或目录)名称,及proj_id参数指定的数字,ftok函数为IPC对象生成一个唯一性的键值。
在实际应用中,很容易产生的一个理解是,在proj_id相同的情况下,只要文件(或目录)名称不变,就可以确保ftok返回始终一致的键值。然而,这个理解并非完全正确,有可能给应用开发埋下很隐晦的陷阱。 因为ftok的实现存在这样的风险,即在访问同一共享内存的多个进程先后调用ftok函数的时间段中,如果pathname指定的文件(或目录)被删除且重新创建,则文件系统会赋予这个同名文件(或目录)新的i节点信息,于是这些进程所调用的ftok虽然都能正常返回,但得到的键值却并不能保证相同。由此可能造成的后果是,原本这些进程意图访问一个相同的共享内存对象,然而由于它们各自得到的键值不同,实际上进程指向的共享内存不再一致;如果这些共享内存都得到创建,则在整个应用运行的过程中表面上不会报出任何错误,然而通过一个共享内存对象进行数据传输的目的将无法实现。
   AIX、Solaris、HP-UX均明确指出,key文件被删除并重建后,不保证通过ftok得到的键值不变。

shmat

AIX上:
对于64位进程,同一进程可连接最多268435456个共享内存段;
对于32位进程,同一进程可连接最多11个共享内存段,除非 使用扩展的shmat;
事实上,同时拥有几十个甚至上百个处理线程的应用并不少见。对于32位进程,一旦超过这个限制值,则所有后续的处理线程都将无法正常工作,从而导致应用运行失败。

32位和64位应用兼容问题

在HP-UX平台上,如同时运行32位应用和64位应用,且它们访问的是一个相同的共享内存区,则会遇到兼容性问题。
在HP-UX中,应用程序设值IPC_CREAT标志调用shmget,所创建的共享内存区,只可被同类型的应用所访问;即32位应用程序所创建的共享内存区只可被其他的32位应用程序访问,同样的,64位应用程序所创建的共享内存区只可被其他的64位应用程序访问。
如果,32位应用企图访问一个由64位应用创建的共享内存区,则会在调用shmget时失败,得到EINVAL错误码
解决方案:当64位应用创建共享内存时,合并IPC_CREAT标志,同时给定IPC_SHARE32标志:
shmget(mem_key,size,0666|IPC_CREAT|IPC_SHARE32);
对于32位应用,设置IPC_SHARE32标志不会带来任何问题,即,无论应用程序将被编译为32位还是64位模式,都可采用如上相同的代码;并由此解决32位应用和64位应用在共享内存访问上的兼容性问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值