《mmap系统调用详解》

积累经验、传递知识、共同进步,让个人与团队都能实现价值增长!😊

📢本文将详细介绍mmap系统调用。​
一、什么是mmap​ 

mmap/munmap函数是用户空间中常用的系统调用函数,无论是在用户程序中分配内存、读写大文件、链接动态库文件,还是多进程间共享内存,都可以看到mmap/munmap函数的身影。mmap/munmap函数的声明如下:

#include <sys/mman.h>

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *addr, size_t length);

 mmap/munmap函数的参数如下:​
•start:用于指定映射到进程地址空间的起始地址,为了提高应用程序的可移植性,一般设置为NULL,让内核来分配一个合适的地址。​

len:表示映射到进程地址空间的大小。​

prot:用于设置内存映射区域的读写属性等。​

flags:用于设置内存映射的属性,如共享映射、私有映射等。​

fd:表示这是一个文件映射,fd是打开的文件的句柄。​
•offset:在文件映射时,表示文件的偏移量。​
prot参数通常表示映射页面的读写权限,有如下参数组合:​
•PROT_EXEC:表示映射的页面是可以执行的。​
•PROT_READ:表示映射的页面是可以读取的。​
•PROT_WRITE:表示映射的页面是可以写入的。​
•PROT_NONE:表示映射的页面是不可访问的​flags参数是一个很重要的参数,可以设置为以值:​
•MAP_SHARED:创建一个共享映射的区域。多个进程可以通过共享映射方式来映射一个文件,这样其他进程也可以看到映射内容的改变,修改后的内容会同步到磁盘文件中。​
•MAP_PRIVATE:创建一个私有的写时复制的映射。多个进程可以通过私有映射的方式来映射一个文件,这样其他进程不会看到映射内容的改变,修改后的内容也不会同步到磁盘文件中。​
•MAP_ANONYMOUS:创建一个匿名映射,即没有关联到文件的映射。​
•MAP_FIXED:使用参数addr创建映射,如果在内核中无法映射指定的地址,那么mmap会返回失败,参数addr要求按页对齐。如果addr和length指定的进程地址空间和已有的VMA重叠,那么内核会调用do_munmap()函数把这段重叠区域销毁,然后重新映射新的内容。​
•MAP_POPULATE:对于文件映射来说,会提前预读文件内容到映射区域,该特性只支持私用映射。​通过参数fd可以看出mmap映射是否和文件相关联,因此在Linux内核中,映射可以分成匿名映射和文件映射。​
•匿名映射:没有映射对应的相关文件,匿名映射的内存区域的内容会初始化为0。​
•文件映射:映射和实际文件相关联,通常把文件内容映射到进程地址空间,这样应用程序就可以像操作进程地址空间一样读写文件

二、mmap映射类型​

1. **私有匿名映射(Private Anonymous Mapping)**:
   - 这种映射不与任何文件关联,通常用于程序堆空间的分配。由于是私有的,映射区域的修改不会反映到任何文件或其它进程中。
   - 这种映射对于实现进程的堆内存管理非常有用,因为它允许操作系统自动管理内存的分配和释放。

2. **共享匿名映射(Shared Anonymous Mapping)**:
   - 与私有匿名映射类似,共享匿名映射也不与文件关联,但它允许多个进程共享映射区域。这意味着一个进程对映射区域的修改对其它所有共享该区域的进程可见。
   - 这种映射通常用于父子进程之间的通信,或者在需要在多个进程间共享数据时使用。

3. **私有文件映射(Private File Mapping)**:
   - 私有文件映射将文件内容映射到内存中,每个进程看到的是文件内容的一个私有副本。对映射区域的修改不会写回到文件中,而是在进程终止时丢弃。
   - 这种映射类型常用于加载动态链接库,因为每个进程都需要自己的库代码副本,以避免多个进程间潜在的冲突。

4. **共享文件映射(Shared File Mapping)**:
   - 共享文件映射也是将文件内容映射到内存,但与私有文件映射不同,这种映射允许多个进程共享对文件内容的读写访问。对映射区域的修改会反映到文件中,所有进程看到的是相同的文件内容。
   - 这种映射类型适用于多进程之间的通信,因为它允许进程间通过共享内存区域直接交换数据。

### mmap的常用标志参数组合:

- 私有匿名映射:`MAP_ANONYMOUS | MAP_PRIVATE`
- 共享匿名映射:`MAP_ANONYMOUS | MAP_SHARED`
- 私有文件映射:通常只使用`MAP_PRIVATE`,文件描述符`fd`指向要映射的文件。
- 共享文件映射:使用`MAP_SHARED`,文件描述符`fd`指向要映射的文件。

### 注意事项:

- 使用mmap进行内存映射时,需要考虑映射的大小、对齐和保护属性。
- 映射建立后,应使用munmap来撤销映射,释放占用的资源。
- mmap和munmap的使用需要谨慎,不当的使用可能导致内存泄漏或其他资源管理问题。

通过这些映射类型,mmap和munmap为程序员提供了强大的工具,以满足不同的内存管理和进程间通信需求。
 

  • 19
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值