曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 4917|回复: 1
打印 上一主题 下一主题

mmap

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2009-2-14 18:11:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
UNIX 提供一个有用的设备,允许程序共享内存;一个好消息是,在 2.0 以后的 Linux 内核中已经包含有这个工具。mmap (for memory map 内存映射)函数 设置内存中的段可以被两个或多个程序读取或写入。一个程序所作的改变可以被其它人看到。

你可以使用相同的设备去操作文件。你可以使一个磁盘文件的条目内容看起来像是内存中的一个数组。如果文件包括的记录可以被 C 结构体所描述,那么你可以使用结构体数组访问来更新这个文件。

通过使用特别权限设置的虚拟内存段使得这看起来是可能的。读取或写入一个段引起操作系统去读或写一个磁盘文件的相应的部分。

mmap 函数创建一个内存区域指针,这个区域关联着可以通过打开文件描述符访问的文件的内容。

用法
#include <sys/mman.h>
void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);

参数 fildes 是打开的文件描述符,mmap() 就是通过这个文件描述符对打开的文件进行内存映射。

参数 addr 用来指定所映射的内存起始地址,但从移植性的角度出发,建议此值设为 0 ,毕竟不同的系统,可用的虚拟地址范围是不同的。

参数 len 表示要映射多大的内存空间

参数 off 用来指示对映射空间的定位。

prot 参数用来设置内存段(memory segment)访问权限,这些值可用来 OR 运算:

PROT_READ : 段可读
PROT_WRITE : 段可写
PROT_EXEC : 段可执行
PROT_NONE : 段不能访问

通过程序在别处的反映,flags 参数控制内存段做怎样的改变。这些选项如下:

MAP_PRIVATE  段为私有,只能由本程序可见,其他进程不可见。
MAP_SHARED  共享给其他的进程,其他进程对此段可见。
MAP_FIXED     段必须在给定的地址上(addr)

msync 函数引起写回(或从中读取)到映射文件中的内存段的部分或全部改变。
#include <sys/mman.h>
int msync(void *addr, size_t len, int flags);

通过传递的开始地址(addr)和长度(len)就能确定需要更新的那部分段。使用以下选项,flags 参数控制更新应该如何进行:

MS_ASYNC            执行异步写
MS_SYNC             执行同步写
MS_INVALIDATE      从文件中读回

nummap 函数释放内存段:
#include <sys/mman.h>
int munmap(void *addr, size_t len);

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
沙发
 楼主| 发表于 2009-2-15 16:55:00 | 只看该作者
SYNOPSIS
       #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 地址开始。后面的这个地址仅作为一个提示,通常指定为 0 。实际所映射的地方由 mmap() 返回。(即 mmap 返回映射到内存中的那段内容的起始地址,这个指针为 void 型,后续对指针的应用根据映射的实际内容类型进行指针的强制转换,如把指针转换为一个结构体类型。因为映射的内容是由一个个的结构体数据组成。)

   prot 参数(parameter,argument)描述了内存的保护方式。它不是 PROT_NONE 就是由一个或多个其它的 PROT_* 标志经过 OR 运算组合。

 
      PROT_EXEC  Pages may be executed.(页可以执行<在另外一些著作上也成为段,如上个帖子中>)

       PROT_READ  Pages may be read.(页可以读)

       PROT_WRITE Pages may be written.(页可以写)

       PROT_NONE  Pages may not be accessed.(页不能访问)

flags 参数指明被映射内容的类型,  映射选项以及对页拷贝的映射所做的修改对进程来说是否是私有的还是用来个共享的.

MAP_FIXED
如果已经指定了一个,就不要再选择不同的地址了。如果由 start 和 len 指定的内存区域与已经存在的映射重叠,那原先已映射且被重叠的那部分将被忽略。如果指定的地址没法用,mmap() 就会失败。如果指定 MAP_FIXED ,start 必须是一个页大小的倍数。使用这个选项往往令人感到沮丧。

MAP_SHARED
对也要对这些内容进行映射的所有其它进程共享这块映射。往这块区域存储等同于向文件中进行写操作。实际上,文件直到 msync 或 munmap 被调用才可能被更新。

MAP_PRIVATE
创建一个copy-on-write(写拷贝?)的私有映射。存储向这个区域的内容不会影响原始文件。这没有指明在 mmap 调用在已映射区域可见后文件是否已经被改变。

一个文件以页大小的整数倍进行映射。对于一个不到一个页大的文件,在映射时,剩下的内存都被设为 0,并且写往这个区域的内容也不会写出到文件上。一个映射在页上的基本文件大小的改变的影响是否也对应着增加或移除文件在内存中的相应域没有并未指明。
(The effect of changing the size of the underlying file of a mapping on  the pages  that  correspond  to  added  or  removed  regions of the file is unspecified.)
      
munmap 系统调用删除指定地址范围的映射,这也会引起此范围内的地址引用产生无效的内存引用。当进程终结时内存域也会自动的卸载映射。另一方面,关闭文件描述符不会卸载内存域映射。

start 所指的地址必须是一个页的整数倍。所有包含指示范围的页都要卸载映射(unmapped),然后这些页的引用将产生 SIGSEGV。如果指示范围没有包含任何映射页这就不是错误。


举例见:
http://www.groad.net/bbs/read.php?tid=594






      
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-7 11:41 , Processed in 0.084832 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表