嵌入式Linux系统编程学习之二十三 System V 共享内存机制


前言

  共享内存也是进程间(进程间不需要有继承关系)通信的一种常用手段。一般 OS 通过内存映射与页交换技术,使进程的内存空间映射到不同的物理内存,这样能够保证每个进程运行的独立性,不至于受其他进程的影响。但可以通过共享内存的方式,使不同进程的虚拟内存映射到同一块物理内存,一个进程往这块物理内存中更新数据,其他进程可以立即看到这块物理内存中修改的内容。
  内存映射和共享内存的区别为:内存映射跟普通文件的读写相比,加快了对文件/设备的访问速度;共享内存是多进程间通信。
  System V 共享内存机制的原理及实现:System V IPC 机制下的共享内存本质是一段特殊的内存区域,进程间需要共享的数据被放在该共享内存区域中,所有需要访问该共享区域的进程都要把该共享区域映射到本进程的地址空间中去,这样一个使用共享内存的进程可以将信息写入该空间,而另一个使用共享内存的进程又可以通过简单的内存读操作获取刚才写入的信息,使得两个不同进程之间进行了一次信息交换,从而实现进程间的通信。
  共享内存允许一个或多个进程通过同时出现在它们的虚拟地址空间的内存进行通信,而这块虚拟内存的页面被每个共享进程的页表条目所引用,同时并不需要在所有进程的虚拟内存中都有相同的地址。
  进程对象对于共享内存的访问通过 key(键)来控制,同时通过 key 进行访问权限的检查。

  函数定义如下:

	#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 *shmat(int shmid, const void *shmaddr, int shmflg);
	int shmdt(const void *shmaddr);
	int shmctl(int shmid, int cmd, struct shmid_ds *buf);

一、ftok 函数

  函数 ftok 用于创建一个关键字,可以用该关键字关联一个共享内存段。
  参数 pathname 为一个全路径文件名,并且该文件必须可访问;
  参数 proj_id 通常传入一非 0 字符。
  通过 pathname 和 proj_id 组合可以创建唯一的 key(对任何进程都是唯一且相同的)。
  如果调用成功,返回一关键字,否则返回 -1。

二、shmget 函数

  函数 shmget 用于创建或打开一个共享内存段,该内存段由函数的第一个参数标识。函数成功则返回一个该共享内存段的唯一标识号(唯一的标识了这个共享内存段),对任何进程都是唯一且相同的,后面会用到。
  参数 key 是一个与共享内存段相关联的关键字,如果事先已经存在一个与指定关键字关联的共享内存段,则直接返回该内存段的标识。key 的值既可以用 ftok 函数产生,也可以是 IPC_RPIVATE (用于创建一个只属于创建进程的共享内存,主要用于父子通信),表示总是创建新的共享内存段。
  参数 size 指定共享内存段的大小,以字节为单位。
  参数 shmflg 是一个掩码合成值,可以是访问权限值与 IPC_CREAT 或 IPC_EXCL 的合成。IPC_CREAT 表示如果不存在该内存段,则创建它;IPC_EXCL 表示如果该内存段存在,则函数返回失败结果(-1)。
  如果调用成功,返回内存段标识,否则返回 -1。

三、shmat 函数

  函数 shmat 将共享内存段映射到进程空间的某一地址。
  参数 shmid 是共享内存段的标识,通常应该是 shmget 的成功返回值。
  参数 shmaddr 指定的是共享内存连接到当前进程中的地址位置。通常是 NULL,表示让系统来选择共享内存出现的地址。
  参数 shmflg 是一组位标识,通常为 0 即可。
  如果调用成功,返回映射后的进程空间的首地址,否则返回 (void *) -1。

四、shmdt 函数

  函数 shmdt 用于将共享内存段与进程空间分离。
  参数 shmaddr 通常为 shmat 的成功返回值。
  函数成功时返回 0,失败时返回 -1。
  注意:将共享内存分离并没有删除它,只是使得该共享内存对当前进程不再可用。

五、shmctl 函数

  函数 shmctl 是共享内存的控制函数,可以用来删除共享内存段。
  参数 shmid 是共享内存段标识,通常应该是 shmget 的成功返回值。
  参数 cmd 是对共享内存段的操作方式,可选为 IPC_STAT、IPC_SET、IPC_RMID。通常为 IPC_RMID,表示删除共享内存段。
  参数 buf 是表示共享内存段的信息结构体数据,通常为 NULL。
  例如:

	shmctl(kshareMem, IPC_RMID, NULL)	//表示删除共享内存段 kshareMem

补充

  调用函数时若检查语法无错误,运行时报段错误,可尝试在root权限下运行。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值