进程间通信---共享内存

栏目: IT技术 · 发布时间: 6年前

内容简介:共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。

一、IPC(Inter-Process Communication,进程间通信)对象的介绍

System V 的IPC对象有共享内存、消息队列、信号灯。

进程间通信---共享内存

注意:在IPC的通信模式下,不管是使用消息队列还是共享内存,甚至是信号灯,每个IPC的对象都有唯一的名字,称为”键”(key)。通过”键”,进程能够识别所用的对象。”键”与IPC对象的关系就如同文件名称于文件,通过文件名,进程能够读写文件内的数据,甚至多个进程能够公用一个文件。而在 IPC的通讯模式下,通过”键”的使用也使得一个IPC对象能为多个进程所共用。

二、共享内存的介绍

<1>共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。

<2>为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。进程就可以直接读写这一块内存而不需要进行数据的拷贝,从而大大提高效率。

<3>由于多个进程共享一段内存,因此也需要依靠某种同步机制。

三、共享内存的特点

进程间通信---共享内存

四、共享内存的操作流程

<1>创建/打开共享内存

<2>映射共享内存,即把指定的共享内存映射到进程的地址空间用于访问

<3>撤销共享内存映射

<4>删除共享内存对象

五、相关 API

A.获取一块共享内存

进程间通信---共享内存

功能:分配一块共享内存

返回值:

调用成功返回一个shmid(类似打开一个或创建一个文件获得的文件描述符一样);

调用失败返回-1。

参数说明:

<1>key标识共享内存的键值(就像文件的标识是文件名):0  / IPC_PRIVATE。

当key的取值为IPC_PRIVATE,则函数shmget()将创建一块新的共享内存;

如果key的取值为0,而参数shmflg中设置了IPC_CREATE这个标志,则同样创建一块新的共享内存。

通过这种方式分配的共享内存,一般用来亲缘关系的进程间通信。

注意:我们一般是通过ftok这个函数获取键值

功能 : 获取一个IPC对象的键值

参数说明:

pthname就是你指定文件名的路径(该文件必须是存在而且可以访问的),一般情况我们都写一个目录

proj_id  : 和pthname一起完成创建键值的参数,虽然为int,但是只有8个比特被使用。一般我们写一个字符代替。

例如:

案例:

进程间通信---共享内存

运行的结果:

进程间通信---共享内存

<2>size是要建立共享内存的长度。所有的内存分配操作都是以页为单位的。所以如果一个进程只申请一块只有一个字节的内存,内存也会分配整整一页(在i386机器中一页的缺省大小PACE_SIZE = 4096字节)。

<3>shmflg有效的标志包括IPC_CREAT 和IPC_EXCL,他们的功能与open()的O_CREAT和O_EXCL相当。

IPC_CREAT      如果共享内存不存在,则创建一个共享内存,否则直接打开已存在的
IPC_EXCL        只有在共享内存不存在的时候,新的共享内存才建立,否则就产生错误

例子一:假设键值为key,创建一个共享内存大小为4k,访问权限为066,如果已经存在则返回其标识号

例子二、假设键值为key,创建一个共享内存大小为1k,访问权限为0666,如果已经存在则报错

B.共享内存的映射

进程间通信---共享内存

函数shmat将标识号为shmid共享内存映射到调用进程的地址空间中。

参数说明:

shmid  :  要映射的共享内存区标识符

shmaddr  :  将共享内存映射到指定地址(若为NULL,则表示由系统自动完成映射)

shmflg  :  SHM_RDONLY  共享内存只读

默认0:共享内存可读写。

返回值 :调用成功放回映射后的地址 ,出错放回(void *)-1;

C.取消共享内存与用户进程之间的映射

进程间通信---共享内存

参数shmaddr是shmat映射成功放回的地址。

注意:当一个进程不再需要共享内存段时,它将调用shmdt()系统调用取消这个段,但是,这并不是从内核真正地删除这个段,而是把相关shmid_ds结构的shm_nattch域的值减1,当这个值为0时,内核才从物理上删除这个共享段。

D.控制共享内存

进程间通信---共享内存

参数说明:

shmid  共享内存标识ID

cmd      IPC_STAT得到共享内存的状态
IPC_SET改变共享内存的状态
IPC_RMID删除共享内存

buf  是一个结构体指针。IPC_STAT的时候,取得的状态放在这个结构体中。如果要改变共享内存的状态,用这个结构体指定;

进程间通信---共享内存
注意:

1.IPC_RMID命令实际上不从内核删除一个段,而是仅仅把这个段标记为删除,实际的删除发生最后一个进程离开这个共享段时。

2.当cmd为IPC_RMID时,第三个参数应为NULL。呵呵,大部分我们都是这样做,用这个函数删除共享内存。

案例探究:

运行结果:

进程间通信---共享内存


以上所述就是小编给大家介绍的《进程间通信---共享内存》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learning PHP & MySQL中文版

Learning PHP & MySQL中文版

车立红 / 中国电力出版社 / 2007-06 / 36.00元

《Learning PHP & MySQL中文版》将介绍程序、模板和数据库的工作原理,讲述如何应对其中的挑战,并彻底地探索这些技术。一起来看看 《Learning PHP & MySQL中文版》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

随机密码生成器
随机密码生成器

多种字符组合密码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换