存储映射I/O-mmap
1.概念
将一个磁盘文件映射到存储空间的一个缓冲区上,读写缓冲区相当于读写磁盘文件。
2.使用
#include<sys/mman.h>
void *mmap(void *addr, size_t len, int prot, int flag, int fd, off_t off);
- addr参数指定映射存储区的起始地址,但通常设置为0,表示由系统选择起始地址,函数返回值为该映射存储区的起始地址。
- len参数是映射的字节数,也就是文件的大小。
- fd参数指定要被映射文件的描述符。
- off参数是要映射字节在文件中的起始偏移量。
- prot参数指定映射存储区的保护要求,但是不能超过文件open模式访问权限。
- flag参数影响映射存储区的多种属性。
子进程能通过fork继承存储区,但是新程序不能通过exec继承存储映射区。
-prot参数
prot | 说明 |
---|---|
PROT_READ | 映射区可读 |
PROT_WRITE | 映射区可写 |
PROT_EXEC | 映射区可执行 |
PROT_NONE | 映射区不可访问 |
这四个参数可任意组合,使用按位与组合。
-flag参数
flag | 说明 |
---|---|
MAP_FIXED | 返回值必须为addr,但是不利于移植不推荐使用,如未使用此标志但addr非0,则内核视addr为一个建议不保证使用addr的地址,建议使用0。 |
MAP_SHARED | 指定存储操作修改映射文件,相当于对该文件write,必须指定此标志或MAP_PRIVATE,但不能同时指定这两个。 |
MAP_PRIVATE | 创建一个该映射文件的一个私有副本,所有后来的引用都使用该副本,任何修改都只影响存储区不会对文件有任何更改(也可用于调试)。 |
相关信号
- SIGSEGV-进程访问不对它访问的映射存储区将发出此信号。例如,映射区被mmap设置为只读,进程在写入时将产生此信号。
- SIGBUS-访问映射存储区时某个部分已不存在将发出此信号,例如,一个进程在访问某个部分之前已经有另一个进程把该部分的内容截断将产生此信号。
相关函数
1. mprotect
调用mprotect可更改一个现有映射的权限
int mprotect(void *addr, size_t len, int prot);
- addr的值必须是系统页长的整数倍。
- prot参数与mmap中的一样。
2. fsync
调用fsync可讲该页冲洗到映射的文件中。
int msync(void *addr, size_t len, int flags);
- 地址与页边界对齐。
- flags参数
- MS_ASYNC,简单的调试要写的页。
- MS_SYNC,在返回之前等待完成。上面这两个一定二选一。
- MS_INVALLIDATE,可选标记允许我们通知系统丢弃那些与底层存储器没有同步的页。
3. munmap
调用munmap解除映射区,在进程终止时系统也会自动解除存储映射区。
int munmap(void *addr, size_t len);
- 关闭所映射的文件描述符并不会解除映射区。
- munmap不影响被映射对象,也就是调用后并不会将映射区内容写入文件。