简介
存储映射I/O使一个磁盘文件与存储空间中的一个缓冲区映射,于是当从缓冲区中取数据,就相当于读文件中的相应字节。于此类似,将数据存入缓冲区,则相应的字节就自动写入文件,这样,就可在不不适用read和write函数的情况下,使用地址(指针)完成I/O操作。
1、使用场景
UNIX网络编程第二卷进程间通信对mmap函数进行了说明。该函数主要用途有三个:
(1) 将一个普通文件映射到内存中,通常在需要对文件进行频繁读写时使用,这样用内存读写取代I/O读写,以获得较高的性能。
(2)将特殊文件进行匿名内存映射,可以为关联进程提供共享内存空间。
(3)为无关联的进程提供共享内存空间,一般也是将一个普通文件映射到内存中。
2.调用函数 介绍
匿名映射/文件映射
mmap按照映射的类型主要可以分为文件映射和匿名映射。
文件映射:文件映射是将一个文件的一部分直接映射到调用进程的虚拟内存中,一旦一个文件被映射之后就可以通过在相应内存区域中操作字节来访问文件内容了。映射的分页会在需要的时候从文件中(自动)加载。这种映射被称为基于文件映射或内存映射文件。
匿名映射:一个匿名映射没有相应的文件。相反,这种映射的页面会被初始化为0.
同时又按照私有映射(MAP_PRIVATE)和共享映射分别将文件映射和匿名映射划分成不同使用用途:
使用方法:
匿名映射
匿名映射没有对应文件映射,其创建方法有两种:
在flags中指定MAP_ANONYMOUS并将fd指定为-1
打开/dev/zero设备文件并将得到的文件描述符传递给mmap.。/dev/zero是一个虚拟设备,当从中读取数据时它总是会返回0,而写入到这个设备中的数据总是被丢弃。/dev/zero的一个常见用途使用0来组装一个文件。
文件映射
文件映射创建需要执行下面的步骤:
获取文件的一个描述符,通常通过调用open()来完成。
将文件描述符作为fd参数传入mmap()调用。
总结:
内存映射I/O所带来的性能优势在大型文件中执行重复随机访问时最有可能体现出来。如果顺序访问一个文件,并假设执行I/O时使用的缓冲区大小足够大以至于能够避免执行大量的I/O系统调用,那么与read()和write()相比,mmap带来的性能上的提升就非常有限或者说根本就没有带来性能上的提升。性能提升的幅度之所以非常有限的原因是不管使用何种技术,真个文件的内容在磁盘和内存之间只传输一次,效率的提高主要得益于减少了用户空间和内核空间之间得一次数据传输,并且与磁盘I/O所需得时间相比,内存使用量得降低通常是可以忽略的。
使用样例: