注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

断弦的博客

做有理想的程序猿

 
 
 

日志

 
 
 
 

mmap的用法(转)  

2011-12-01 12:27:38|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

名字

mmap, munmap - 把文件或设备映射或解除映射到内存中

概要

#include <sys/mman.h>
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *start, size_t length);

描述

mmap()函数请求将由fd指定的文件(或其它对象)中从偏移量offset处开始的 length长度的字节映射到内存中,所映射的内存地址建议在start处。start地址只是做提示用,实现上通过指定为0,对象被映射的实际地址由mmap()返回。

prot 参数指定期望的内存保护模式(不要与文件的打开模式混淆)。它的值可能为PROT_NONE,或者下面这些标志值相或得到的值:

PROT_EXEC
内存页可能被执行。
PROT_READ
内存页可能被读。
PROT_WRITE
内存页可能被写。
PROT_NONE
内存页不可访问。

flags 参数被映射对象的类型、映射选项以及对映射的内存页拷贝的修改是只限于本进程还是与其它进程共享。它包括以下位:

MAP_FIXED
只选择指定的内存地址。如果由start以及length指定的内在区域与其它已映射的内存区域有重叠,那么重叠的内存部分将被丢弃。如果指定的内存地址不可用,mmap()失败。如果指定了 MAP_FIXED , start 必须是内存页大小的整数倍。这个选项一般不建议使用。
MAP_SHARED
与所有映射该对象的进程共享该映射地址。往映射区域存储数据就相当于写该文件(对象)。文件可能并没有得到更新,直到调用msync(2)munmap(2)
MAP_PRIVATE
创建一个私有的copy-on-write映射。往映射区域里写数据不会影响到原文件。mmap()之后对文件的修改是否会对映射区域有影响,是不确定的。

您必须指定 MAP_SHAREDMAP_PRIVATE中的一个。

上面的三个选项在 POSIX.1-2001中描述。 Linux 也用到下面这些非标准的选项:

MAP_DENYWRITE
已不使用。
MAP_EXECUTABLE
已不使用。
MAP_NORESERVE
不要为这个映射区域保留交换空间。如果保留了交换空间,修改这个映射区域是有可能的。如果没有保留交换空间,如果没有物理空间可用,写映射区域将会得到SIGSEGV 信号。可以参考 /proc/sys/vm/overcommit_memory in proc(5). 在内核2.6之前, 这个选项只会对私有可写映射产生影响。
MAP_LOCKED (since Linux 2.5.37)
用mlock()可以锁写映射到内存中的区域。老的内核中这个选项不可用。
MAP_GROWSDOWN
供栈使用。指示内核VM系统,映射区域在内存中应该向下增长。
MAP_ANONYMOUS
映射区域不对应任何文件。 fdoffset 参数被忽略。这个选项与 MAP_SHARED 一起使用,只在内核 2.4中支持。
MAP_ANON
MAP_ANONYMOUS的别名,已废弃。
MAP_FILE
兼容选项,可忽略。
MAP_32BIT
映射进程空间的前2G区域。当 MAP_FIXED 被指定时,这个选项被忽略。当前这个选项只在x86-64 平台上的64位编程才用到。.
MAP_POPULATE (since Linux 2.5.46)
通过对这个文件做read-ahead(?),为文件映射预留页面表。随后对映射区的访问不会被页面失效(page faults)所阻断。
MAP_NONBLOCK (since Linux 2.5.46)
只有和MAP_POPULATE才有用. 不做read-ahead: 只为已经存在于RAM中的页面创建页面表项。

有些系统文档里可能还包括对 MAP_AUTOGROW, MAP_AUTORESRV, MAP_COPY, 以及 MAP_LOCAL的描述。

除非设置了MAP_ANONYMOUS ,否则fd必须是一个合法的文件描述符. 如果设置了MAP_ANONYMOUS Linux平台会忽略fd,但是有些实现中要求 fd 赋值成 -1,可移植程序应该保证这一点。

offset 必须是页面大小的整数倍。页面大小由 getpagesize(2)得到。

mmap()映射的内存通过 fork(2)调用以相同的属性被保留

被映射的文件大小应该是页面大小的整数倍。如果一个文件大小不是页面大小的整数倍,映射时多出来的区域 将被赋为0,对这些区域的写不会被写回到文件中。

munmap()系统调用将删除指定地址范围内的映射区域。随后对这个范围内区域的引用将产生非法的内存引用。当这个进程终止后,这个区域也会被删除。另一方面,关闭文件描述符并不会删除映射区域。

返回值

调用成功, mmap() 一个映射区域的指针。调用失败,返回MAP_FAILED (也就是, (void *) -1) 相应的errno 也被设置。对于 munmap() ,成功返回0,失败返回-1。errno 也被设置(可能为EINVAL).

注意

是否PROT_READ 会包含PROT_EXEC ,这是与系统体系结构相关的。可移植程序如果想在新映射的区域里执行代码,最好明确地指定PROT_EXEC
  评论这张
 
阅读(56)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018