存储映射I/O能将一个磁盘文件映射到存储空间中的一个缓冲区上,于是,当从缓冲区提取一个数据时,就相当于读文件中的相应字节。
下面的函数告诉内核将一个给定的文件映射到一个存储区域中
#include <sys/mman.h>
void *mmap(void *addr,size_t len,int prot,int flag,int fd,off_t off);
//返回值:若成功返回映射区的起始地址,若出错,返回MAP_FAILED
- addr参数用于指定映射存储区的起始地址。通常将其设置为0,这表示由系统选择该应摄取的起始地址。
- fd参数是指定要被映射文件的描述符。在文件映射到地址空间之前,必须先打开该文件。
- len参数是映射的字节数
- off参数是要映射字节在文件中的起始偏移量
- prot参数指定了映射存储区的保护要求,对指定映射存储区的保护要求不能超过文件open模式的访问权限。
prot | 说明 |
PROT_READ | 映射区可读 |
PROT_WRITE | 映射区可写 |
PROT_EXEC | 映射区可执行 |
PROT_NONE | 映射区不可访问 |
- 下面是flag参数映像映射存储区的多种属性。
MAP_FIXED | 返回值必须等于addr.因为这不利于可移植性,所以不鼓励使用此标志 |
MAP_SHARED | 这一标志描述了本进程对映射区所进行的存储操作配置。此标志指定存储操作修改映射文件,也就是,存储操作相当于对该文件进行write |
MAP_PRIVATE | 本标志说明,对映射区的存储操作导致创建该映射文件的一个私有副本。所有后来对该映射区的引用都是引用该副本。 |
与映射区有关的信号有SIGSEGV和SIGBUS。
信号SIGSEGV通常同于指示进程试图访问对它不可用的存储区。如果映射存储区被mmap指定成了只读的,那么进程试图将数据存入这个映射存储区的时候,也会产生此信号。
如果映射区的某个部分在访问时已经不存在,则产生SIGBUS信号。
调用mprotect可以更改一个现有映射的权限
#include <sys/mman.h>
int mproject(void *addr,size_t len,int prot);
//返回值:成功返回0,出错返回-1
参数addr的值必须是系统页长的整数倍。
如果共享映射中的页已经被修改,那么可以调用msync将该页冲洗到被映射的文件中。
#include <sysmman.h>
int msync(void *addr,size_t len,int flags);
//返回值:若成功返回0,失败返回-1
flags参数使我们对如何冲洗存储区有某种程度的控制。可以指定MS_ASYNC标志来简单调式要写的页。如果希望返回之前等待写操作完成,则可指定MS_SYNC标志。一定要指定MY_ASYNC和MS_SYNC中的一个。
当进程终止的时候,会自动解除存储映射区的映射,或者直接调用munmap函数也可以解除映射区。关闭映射存储区时使用的文件描述符并不解除映射区。
#include <sys/mman.h>
int munmap(void *addr,size_t len);
//返回值若成功返回0,出错返回-1