mmap介绍mmap是一个linux系统调用接口作用是让进程把打开的文件映射到自己的地址空间内给用户返回虚拟地址往后操作文件就不用做系统调用了可以通过虚拟地址对文件操作。普通的文件访问方法是通过fd走系统调用用户与内核间会频繁来回数据拷贝。文件创建出来缓冲区也能申请好只要把地址空间与缓冲区映射就能通过虚拟地址访问。这有点类似共享内存或者说这就是另一种共享内存再来一个进程同样可以映射就完成了不同进程数据共享。所以mmap不仅可以实现单纯文件操作也能完成共享内存的功能。mmap的使用#includesys/mman.h//需要包含的头文件void*mmap(void*addr,size_tlength,intprot,intflags,intfd,off_toffset);返回值成功返回虚拟地址起始地址失败返回MAP_FAILED即-1的强转参数addrmmap可以指明具体地址传入NULL让系统给我们分配推荐length要映射的文件的大小。不一定从偏移量为0开始访问length可调整。length是系统内存页的整数倍内部会上下取整和共享内存一样prot权限设置PROT_READ可读PROT_WRITE可写… …flags映射类型MAP_SHARED在使用虚拟地址访问时会同步到文件MAP_PRIVATE不与文件挂钩单纯的开辟空间使用和malloc一样效果fd文件描述符文件的唯一性标识选择要映射的文件描述符。offset文件映射起始偏移字节映射区间为[offset, offset length)注意在使用mmap操作文件时它没打开文件功能也没有自动扩容功能所以要先打开文件然后根据需要进行文件大小调整。关闭文件映射intmunmap(void*addr,size_tlength);返回值成功0失败-1参数addr文件的起始地址length文件大小示例代码#includeiostream#includesys/mman.h#includesys/types.h#includesys/stat.h#includefcntl.h#includeunistd.h#definePAGE_SIZE4096intmain(intargc,char*argv[]){if(argc!2){std::cerrUsage: argv[0] filenamestd::endl;return1;}// 1. 打开文件intfdopen(argv[1],O_RDWR|O_CREAT|O_TRUNC,0666);if(fd0){std::coutfile open failstd::endl;return2;}// 2. 调整文件大小if(::ftruncate(fd,PAGE_SIZE)-1){std::coutftruncate failstd::endl;return3;}//3. 文件映射char*shmaddr(char*)::mmap(NULL,PAGE_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);if(shmaddrMAP_FAILED){std::coutmmap failstd::endl;return4;}//4. 操作文件for(charca;cz;c){shmaddr[c-a]c;sleep(1);}//5. 关闭文件映射if(::munmap(shmaddr,PAGE_SIZE)-1){std::coutmunmap failstd::endl;return5;}::close(fd);return0;}输出结果打开文件查看内容vim log.txt文件并未被使用的空间会被0填充^的ASCII值就是0注意正常情况下需要获取一下文件大小。手动调整文件大小特别是空文件mmap不会扩容只是对既定的文件映射不像write一样自动扩容。模拟实现malloc以上讲的都是map_shared映射类似而map_private创建私有的地址空间给自己进程使用这种映射方式也叫匿名映射。和文件就没有任何关系了malloc底层调用有时候使用的就是mmap。将权限设为可读可写文件描述符设置为负一设置标志位MAP_PRIVATE | MAP_ANONYMOUS作用是创建一个与任何文件都无关的、匿名的内存映射。它分配的内存是被初始化为全零的。示例代码#includeiostream#includesys/mman.h#includesys/types.h#includesys/stat.h#includefcntl.h#includeunistd.hvoid*my_malloc(intsize){void*ptrmmap(NULL,size,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);if(ptrMAP_FAILED){std::coutmy_malloc failstd::endl;returnnullptr;}returnptr;}voidmy_free(void*ptr,intsize){if(munmap(ptr,size)-1){std::coutmy_free failstd::endl;}}intmain(){intsize1024;char*ptr(char*)my_malloc(size);if(!ptr)return1;for(charca;cz;c){ptr[c-a]c;std::coutptr[c-a] ;}std::coutstd::endl;my_free(ptr,size);return0;}输出结果非常感谢您能耐心读完这篇文章。倘若您从中有所收获还望多多支持呀