11.4.1 内存映射概述

11.4.1 内存映射概述

mmap系统调用的作用是在调用进程的虚拟地址空间中创建一个新的内存映射

根据内存背后有无实体文件与之关联,映射可以分成以下两种:

文件映射:内存映射区域有实体文件与之关联。

  • mmap系统调用将普通文件的一部分内容直接映射到调用进程的虚拟地址空间。
  • 一旦完成映射,就可以通过在相应的内存区域中操作字节来访问文件内容。这种映射也被称为基于文件的映射。

匿名映射:匿名映射没有对应的文件。

  • 这种映射的内存区域会被初始化成0。
  • 一个进程映射的内存可以与其他进程中的映射共享物理内存。所谓共享是指各个进程的页表条目指向RAM中的相同分页。如图11-6所示

 

这种内存映射的共享,会在以下两种情况下发生:

  • 通过fork,子进程继承了父进程通过mmap映射的副本
  • 多个进程通过mmap映射了同一个文件的同一个区域。

无论映射背后有无实体文件与之关联,这个进程之间共享映射的特性都是非常有用的。

我们知道,进程的虚拟地址空间是彼此隔离的,一个进程不能直接操作另一个进程虚拟地址空间中的内存。

但是mmap系统调用给出了两个办法,让多个进程可以共享一片内存区域。

看到第一种方式,即通过fork子进程继承父进程通过mmap映射的副本,大家的心中可能会隐隐有种不安。

第4章曾提到过,虽然子进程拷贝了父进程的内存,但是父子进程的页表并不是始终都指向同一物理内存的,一旦父子进程中有一个尝试修改内存的内容时,内核就不得不发起写时复制,分配新的物理内存

从此父子进程分道扬镳,彼此再也看不到对方对内存的改动。

对于进程malloc出来的内存,栈上的变量的确如此,fork之后父子进程并不是共享同一块映射

但是通过mmap系统调用创建的内存映射却可以做到进程之间共享同一个内存映射。当然进程之间要不要共享映射也是可以选择的,这取决于该映射是私有映射还是共享映射

私有映射(MAP_PRIVATE):在映射内容上发生的变更对其他进程不可见。对于文件映射而言,变更不会同步到底层文件中。对映射内容所做的变更是进程私有的。事实上,内核使用了写时复制技术来完成这个任务。未对映射内容进行修改操作时,页面仍然是共享的。一旦有进程试图修改其中一个分页的内容时,内核首先会为该进程创建一个新的分页,并将需要修改的分页中的内容拷贝到新分页中。

共享映射(MAP_SHARED):在映射内容上发生的所有变更,对所有共享同一个映射的其他进程都可见。对于文件映射而言,变更会同步到底层的文件中。很明显,共享映射是用于进程间通信的。内存映射根据有无文件关联,分成文件与匿名;根据映射是否在进程间共享,分成私有和共享。

这两个维度两两组合,内存映射共分成4种类型,其各自的用途如表11-7所示。

 下面,我们开始介绍如何利用mmap接口,实现这四种不同的内存映射。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值