mmap(2) #include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset); 功能:将文件和设备映射到内存 参数: addr 指示内核分配的地址,linux会分配附近的页,该参数一般为NULL,由内核选择地址建立映射区域 length 指定了映射区域的长度 prot 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_SHARED 共享映射区域 对映射区域的更新可以被另外一个映射同一文件的进程看到,并且同步到底层的文件中 MAP_PRIVATE 私有映射 对映射区域的更新不可以被另外一个映射同一文件的进程看到,并且不同步到底层的文件中 另外 以下的标记可以选择0或多个按位或到flags中,详见man手册 MAP_ANONYMOUS 匿名映射 fd被忽略fd设置为-1 offset被忽略. fd 指定了文件 将这个文件映射到进程的虚拟地址空间里 offset 指定了文件映射的起始位置 这个值必须是页的整数倍 返回值: 错误 MAP_FAILED被返回 errno被设置 成功 返回映射区域的起始地址
int munmap(void *addr, size_t length); 功能 解除文件或设备到内存的映射 参数 addr 指定了映射区域的起始地址 length 指定了长度 返回值 成功 0 错误 -1 errno被设置
匿名映射 物理地址空间 有些设备文件没有文件名.这些设备的确是一个文件但是没有记录到文件管理系统中 这类文件称为匿名文件.个人理解:匿名映射就是建立一个虚拟地址到内存中物理地址的一个映射关系,然后对虚拟内存的操作,会折射到实际的物理内存中,与非匿名映射相比,只是匿名映射时,与文件无关,匿名映射更像是标准C语言中的malloc,calloc等
#ifndef __T_STDIO_H__ #define __T_STDIO_H__ #include <stdio.h> #define E_MSG(STR,VAL) do{\ perror(STR);\ return (VAL);\ }while(0) #endif匿名映射
#include <t_stdio.h> #include <sys/mman.h> #include <string.h> int main(void){ int prot = PROT_READ | PROT_WRITE; int flags = MAP_PRIVATE | MAP_ANONYMOUS; //建立匿名映射,物理地址空间映射到进程的虚拟地址 char *p = (char *)mmap(NULL, 1024, prot, flags, -1, 0); if(p==MAP_FAILED) E_MSG("mmap", -1); //使用p strcpy(p, "hello beijing"); printf("%s\n", p); //解除映射关系 munmap(p,1024); return 0; }文件映射
#include <t_stdio.h> #include <sys/mman.h> #include <t_file.h> int main(int argc, char *argv[]){ int prot = PROT_READ | PROT_WRITE; int flags = MAP_SHARED; //以可读可写的方式打开文件 int fd = open(argv[1], O_RDWR); if(fd == -1) E_MSG("open", -1); //将文件映射到进程的虚拟地址空间 int *p = (int *)mmap(NULL, 6, prot, flags, fd, 0); if(p==MAP_FAILED){ //关闭文件描述符,不解除映射 close(fd); E_MSG("mmap", -1); } //到这里已经建立起映射了 //关闭文件描述符,不解除映射 close(fd); *p = 0x31323334; //解除映射 munmap(p,6); return 0; }