一、mmap简介
mmap是指内存映射,它是一种内存管理方法,早在Unix系统的早期版本中就已经被广泛使用。mmap将一个磁盘文件区域映射到进程地址空间中的一段地址,这样就可以像访问内存一样访问它。
mmap函数通常用于文件的共享内存区域,可以将磁盘文件的一部分直接映射到进程的地址空间中,通过对该区域的读写来完成文件的读写,这种方式避免了频繁的文件I/O操作,从而提高了程序的效率。
二、mmap函数的使用
使用mmap前需要打开需要映射的文件,然后将文件长度扩展至需要的长度。
mmap函数的定义如下:
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); // addr:指定映射的首地址(通常为空指针) // length:映射区域的长度 // prot:映射区域的访问权限(PROT_READ、PROT_WRITE、PROT_EXEC) // flags:映射区域的特性(MAP_SHARED、MAP_PRIVATE) // fd:指定要映射的文件描述符 // offset:指定要映射的文件区域
mmap函数会返回映射区域的指针。
成功调用mmap后,需要使用munmap函数释放映射的内存。
int munmap(void *addr, size_t length); // addr:指定要释放的映射区域的指针 // length:指定要释放的映射区域的长度
三、mmap的优缺点
优点
1、提高文件I/O效率
使用mmap可以将文件的部分区域映射到内存中,从而减少频繁的文件I/O操作,提高程序的效率。
2、共享内存
多个进程可以同时访问同一块内存区域,从而实现内存共享。
缺点
1、限制映射区域的大小
mmap映射区域的大小是受限制的,通常不能超过物理内存的大小。
2、操作磁盘文件风险较高
如果多个进程同时访问同一块映射的内存区域,可能会导致数据不一致的问题,因此需要在使用时加锁。
四、使用示例
示例1:从文件读取内容
以下示例用于从文件中读取内容,并将其打印到控制台上:
#include <iostream> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> int main() { int fd = open("test.txt", O_RDONLY); if (fd < 0) { std::cerr << "open failedn"; return -1; } struct stat st; if (fstat(fd, &st) < 0) { std::cerr << "fstat failedn"; close(fd); return -1; } char *addr = (char*)mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { std::cerr << "mmap failedn"; close(fd); return -1; } write(STDOUT_FILENO, addr, st.st_size); if (munmap(addr, st.st_size) < 0) { std::cerr << "munmap failedn"; } close(fd); return 0; }
示例2:将数据写入文件
以下示例用于将数据写入文件中:
#include <iostream> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> int main() { int fd = open("output.txt", O_RDWR | O_CREAT, 0664); if (fd < 0) { std::cerr << "open failedn"; return -1; } int len = 1024 * 1024; if (ftruncate(fd, len) < 0) { std::cerr << "ftruncate failedn"; close(fd); return -1; } char *addr = (char*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (addr == MAP_FAILED) { std::cerr << "mmap failedn"; close(fd); return -1; } for (int i = 0; i < len; i++) { addr[i] = 'a'; } if (munmap(addr, len) < 0) { std::cerr << "munmap failedn"; } close(fd); return 0; }
五、总结
mmap是一种内存映射的方法,常用于文件的共享内存区域。使用mmap需要打开需要映射的文件,并将文件长度扩展至需要的长度,然后调用mmap函数将文件映射到进程地址空间中的一段地址。成功调用mmap后,需要使用munmap函数释放映射的内存。
mmap的优点是提高了文件I/O效率,以及可以实现内存共享;缺点是映射区域的大小受限制,操作磁盘文件风险较高。