欢迎来到天天文库
浏览记录
ID:14412977
大小:54.00 KB
页数:19页
时间:2018-07-28
《linux共享内存实例及文件映射编程及实现原理》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、Linux共享内存实例及文件映射编程及实现原理Linux共享内存实例及文件映射编程及实现原理.txt没有不疼的伤口,只有流着血却微笑的人有时候给别人最简单的建议却是自己最难做到的。目录(一)IPC共享内存和文件映射的区别1(二)共享内存实现流程总结1(三)存储映射I/O(包含实现原理说明)2文件映射API补充4(四)IPC共享存储(包含实现原理说明)6(五)共享内存实现基本原理10(六)IPC共享内存实现机制11(七)文件映射的实现机制13(一)IPC共享内存和文件映射的区别1.文件映射的页框是磁盘文件高速缓存中的页框,内核线程pdflush会将页框中的内容回写进磁盘
2、,如果是私有映射类型,将会进行写时复制。而IPC共享内存映射的是一种特殊文件系统中的文件高速缓存,它没有相应的磁盘映像。2.IPC共享内存只存在于内存中,系统重新启动,数据将会丢失。而文件共享映射会将数据写回磁盘。3.IPC共享内存的大小是在创建的时候指定,而且大小不能改变,而文件在创建时大小为0,此时还不能建立映射,文件的大小会间接的决定映射区的大小。例如文件的大小是123,而要求映射的区域大小是4096*2,但实际只会分配4096的映射空间,此时引用4096以后的线性空间将引起缺页异常。4.当第一次读取共享内存时IPC共享内存对象将分配一个新的页框,而文件映射分配
3、新页框的同时会将磁盘中的数据写入新页框。5.IPC共享内存不需要写回磁盘操作,完全是为共享内存而设计,所以使用效率会更高。6.IPC共享内存对象必须调用shmctl()显示的撤销,否则会一直保留着,使用key或者id号定位一个共享内存对象,key和id号的对应关系并不是固定的。例如,第一次使用key建立一个共享内存对象为shm1对应的id为id1,之后系统重新启动,然后再使用key建立一个共享内存对象shm2,对应的id是id2,此时id2和id1是不同的。而文件映射使用相同的路径将会定位相同的磁盘文件。总结:IPC共享内存和文件映射的实现机制是一样的,文件映射的目的
4、是加快对文件的读写速度,而IPC共享内存就是为了共享内存而设计的,所以效率会高一些。(二)共享内存实现流程总结1.建立一个线性区对象structvm_area_struct并加入进程的内存描述符current->mm中。函数mmap()和shmat()就是用于建立并注册线性区对象,这个对象中的structfile*vm_file指向映射文件的文件对象,vm_page_prot是线性区中页框的访问许可权。但此时并未修改进程的页表,而是注册相应的缺页异常回调函数,注册在对象的vm_ops。2.当进程第一次访问共享内存区时,由于相应的页表还未填写,将产生缺页异常,并根据线性
5、地址找到对应的线性区对象,然后调用前边注册过的缺页异常回调函数,并根据vm_file文件对象和vm_page_prot的信息来填写相应的页表项,最后重新执行产生缺页异常的代码。说明:文件映射和IPC共享内存映射的物理页框都是磁盘文件的页高速缓存中的,IPC共享内存使用一种特殊文件系统,这个文件系统并没有对应的磁盘映像,只是复用了文件系统的框架。更详细的内容参见后边的五,六,七节。下面3,4节是《UNIX环境高级编程》对文件映射和IPC共享内存的讲解,已经说明的很详细了,我在它的基础上附加了一些内核实现原理的说明,实现原理说明部分放在括号内。(三)存储映射I/O(包含实
6、现原理说明)存储映射I/O使一个磁盘文件与存储空间中的一个缓存相映射。于是当从缓存中取数据,就相当于读文件中的相应字节。与其类似,将数据存入缓存,则相应字节就自动地写入文件。这样,就可以在不使用read和write的情况下执行I/O。为了使用这种功能,应首先告诉内核将一个给定的文件映射到一个存储区域中。这是由mmap函数实现的。#include#includevoid*mmap(voidaddr,size_tlen,intprot,intflag,intfd,off_toff);返回:若成功则为映射区的起始地址,若出错
7、则为-1addr参数用于指定映射存储区的起始地址。通常将其设置为0,这表示由系统选择该映射区的起始地址。此函数的返回地址是:该映射区的起始地址。fd指定要被映射文件的描述符(fd用于定位是哪个磁盘文件的页高速缓存)。在映射该文件到一个地址空间之前,先要打开该文件。len是映射的字节数。off是要映射字节在文件中的起始位移量(下面将说明对off值有某些限制)。在说明其余参数之前,先看一下存储映射文件的基本情况。图12-12显示了一个存储映射文件。在此图中,“起始地址”是mmap的返回值。在图中,映射存储区位于堆和栈之间:这属于实现细节,各种实现之间可能
此文档下载收益归作者所有