加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 服务器 > 搭建环境 > Unix > 正文

UNIX环境高级编程:存储映射I/O(mmap函数)

发布时间:2016-09-27 01:53:33 所属栏目:Unix 来源:站长网
导读:副标题#e# 共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据: 一次从输入文件到共

31-38   读出内存映射区中每个页面的首字节和尾字节,并输出他们的值。我们预期这些值全为0.同时把每个页面的这两个字节设置为1,。我们预期某个引用会最终引发一个信号,它将终止程序。当for循环结束时,我们输出下一页的首字节,并预期这会失败。

运行结果:

huangcheng@ubuntu:~$ ls -l test  
ls: 无法访问test: 没有那个文件或目录  
huangcheng@ubuntu:~$ ./a.out test 5000 5000  
PAGESIZE = 4096  
ptr[0] = 0  
ptr[4095] = 0  
ptr[4096] = 0  
ptr[8191] = 0  
段错误  
huangcheng@ubuntu:~$ ls -l test  
-rwxr-xr-x 1 huangcheng huangcheng 5000 2013-07-09 15:48 test  
huangcheng@ubuntu:~$ od -b -A d test  
0000000 001 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000  
0000016 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000  
*  
0004080 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 001  
0004096 001 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000  
0004112 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000  
*  
0004992 000 000 000 000 000 000 000 040  
0005000

页面大小为4096字节,我们能够读完整的第2页(下标为4096-8191),但是访问第3页时(下标为8192)引发SIGSEGV信号,shell将它输出成"Segmentation Fault(分段障)"。尽管我们把ptr[8191]设置成1,它也不写到test文件中,因而该文件的大小仍然是5000.内核允许我们读写最后一页中映射区以远部分(内核的内存保护是以页面为单位的)。但是我们写向这部分扩展区的任何内容都不会写到test文件中。设置成1的其他3个字节(下标分别为0,4905和4906)复制回test文件,这一点可使用od命令来验证。(-b选项指定以八进制数输出各个字节,-A d选项指定以十进制数输出地址。)UNIX环境高级编程:存储映射I/O(mmap函数)

我们仍然能访问内存映射区以远部分,不过只能在边界所在的那个内存页面内(下标为5000-8191)。访问ptr[8192]将引发SIGSEGV信号,这是我们预期的。

现在我们把内存映射区大小(15000字节)指定成大于文件大小(5000字节)。

huangcheng@ubuntu:~$ ./a.out test 5000 15000  
PAGESIZE = 4096  
ptr[0] = 0  
ptr[4095] = 0  
ptr[4096] = 0  
ptr[8191] = 0  
总线错误  
huangcheng@ubuntu:~$ ls -l test  
-rwxr-xr-x 1 huangcheng huangcheng 5000 2013-07-09 16:00 test

其结果与先前那个文件大小等于内存映射区大小(都是5000字节)的例子类似。本例子引发SIGBUS信号(其shell输出为"Bus Error(总线出错)"),前一个例子则引发SIGSEGV信号。两者的差别是,SIGBUS意味着我们是在内存映射区访问的,但是已超出了底层支撑对象的大小。上一个例子中的SIGSEGV则意味着我们已在内存映射区以远访问。可以看出,内核知道被映射的底层支撑对象(本例子中为文件test)的大小,即使我们访问不了该对象以远的部分(最后一页上该对象以远的那些字节除外,他们的下标为5000-8191)。

UNIX环境高级编程:存储映射I/O(mmap函数)

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读