Linux进程间通信 共享内存
粘附的时候 创建,而要等到第一个进程试图访问它的时候才创建.
Linux为共享内存提供了四种操作. 1. 共享内存对象的创建或获得.与其它两种IPC机制一样,进程在使用共享内存区域以前,通过系统调用sys_ipc (call值为SHMGET)创建一个键值为key的共享内存对象,或获得已经存在的键值为key的某共享内存对象的引用标识符.以后对共享内存对象的访 问都通过该引用标识符进行.对共享内存对象的创建或获得由函数sys_shmget完成,其定义如下: int sys_shmget (key_t key, int size, int shmflg) 这里key是表示该共享内存对象的键值,size是该共享内存区域的大小(以字节为单位),shmflg是标志(对该共享内存对象的特殊要求). 它所做的工作如下: 1) 如果key == IPC_PRIVATE,则创建一个新的共享内存对象. * 算出size对应的页数,检查其合法性. * 搜索向量表shm_segs,为新创建的共享内存对象找一个空位置. * 申请一块内存用于建立shmid_kernel数据结构,注意这里申请的内存区域大小不包括真正的共享内存区,实际上,要等到第一个进程试图访问它的时候 才真正创建共享内存区. * 根据该共享内存区所占用的页数,为其申请一块空间用于建立页表(每页4个字节),将页表清0. * 填写shmid_kernel数据结构,将其加入到向量表shm_segs中为其找到的空位置. * 返回该共享内存对象的引用标识符. 2) 在向量表shm_segs中查找键值为key的共享内存对象,结果有三: * 如果没有找到,在操作标志shmflg中没有指明要创建新共享内存,则错误返回,否则创建一个新的共享内存对象. * 如果找到了,但该次操作要求创建一个键值为key的新对象,那么错误返回. * 否则,合法性、认证检查,如有错,则错误返回;否则,返回该内存对象的引用标识符. 共享内存对象的创建者可以控制对于这块内存的访问权限和它的key是公开还是私有.如果有足够的权限,它也可以把共享内存锁定在物理内存中. 参见include/linux/shm.h 2. 粘附.在创建或获得某个共享内存区域的引用标识符后,还将共享内存区域映射(粘附)到进程的虚拟地址空间,然后才能使用该共享内存区域.系统调用 sys_ipc(call值为SHMAT)用于共享内存区到进程虚拟地址空间的映射,而真正完成粘附动作的是函数sys_shmat,其定义如下: int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr) 其中:shmid是共享内存对象的引用标识符; shmaddr该共享内存区域在进程的虚拟地址空间对应的虚拟地址; shmflg是映射标志; raddr是实际映射的虚拟空间地址. 该函数所做的工作如下: 1) 根据shmid找到共享内存对象. 2) 如果shmaddr为0,即用户没有指定该共享内存区域在它的虚拟空间中的位置,则由系统在进程的虚拟地址空间中为其找一块区域(从1G开始);否则,就 用shmaddr作为映射的虚拟地址. 3) 检查虚拟地址的合法性(不能超过进程的最大虚拟空间大小—3G,不能太接近堆栈栈顶). 4) 认证检查. 5) 申请一块内存用于建立数据结构vm_area_struct,填写该结构. 6) 检查该内存区域,将其加入到进程的mm结构和该共享内存对象的vm_area_struct队列中. 共享内存的粘附只是创建一个vm_area_struct数据结构,并将其加入到相应的队列中,此时并没有创建真正的共享内存页. 当进程第一次访问共享虚拟内存的某页时,所有的共享内存页还都没有分配,会发生一个page fault异常.当Linux处理这个page fault的时候,它找到发生异常的虚拟地址所在的vm_area_struct数据结构.在该数据结构中包含有这类共享虚拟内存的 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |