【操作系统】Linux 写时复制机制原理

Linux的写时复制机制在创建子进程时,通过共享内存页来提高效率并节省内存。当尝试修改内存时,才会复制内存页,这一过程在缺页异常处理中完成。这种机制在AOF持久化等场景中有重要应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【操作系统】Linux 写时复制机制原理

参考资料:

Linux 写时复制机制原理

AOF 持久化是怎么实现的?

在 Linux 系统中,调用 fork 系统调用创建子进程时,并不会把父进程所有占用的内存页复制一份,而是与父进程共用相同的内存页,而当子进程或者父进程对内存页进行修改时才会进行复制 —— 这就是著名的 写时复制 机制。

下面我们将分析 Linux 写时复制(Copy On Write) 机制的原理。

虚拟内存与物理内存

进程的内存可分为 虚拟内存物理内存

  • 物理内存:就是电脑安装的内存条,如果电脑安装了2GB的内存条,那么系统就用于 0 ~ 2GB 的物理内存空间。
  • 虚拟内存:虚拟内存是使用软件虚拟的,在 32 位操作系统中,每个进程都独占 4GB 的虚拟内存空间。

应用程序使用的是 虚拟内存,比如 C 语言取地址操作符号 & 所得到的地址就是 虚拟内存地址。而 虚拟内存地址 需要映射到 物理内存地址 才能使用,如果使用没有映射的 虚拟内存地址,将会导致 缺页异常

虚拟内存地址 映射到 物理内存地址 如下图所示:

主从架构.drawio

如上图所示,进程A与进程B的相同 虚拟内存地址 映射到不同的 物理内存地址,这就是不同进程的相同虚拟内存地址互不影响的原因。

写时复制原理

前面介绍了 虚拟内存物理内存 的概念,接下来将会介绍 Linux 写时复制 的原理。

前面说过,虚拟内存 需要与 物理内存 进行映射才能使用,如果不同进程的 虚拟内存地址 映射到相同的 物理内存地址,那么就实现了共享内存的机制。如下图所示:

主从架构.drawio

由于进程A的 虚拟内存M 与进程B的 虚拟内存M' 映射到相同的 物理内存G,所以当修改进程A 虚拟内存M 的数据时,进程B 虚拟内存M' 的数据也会跟着改变。

Linux 为了加速创建子进程过程与节省内存使用的原因,实现了 写时复制 的机制。

写时复制 的原理大概如下:

  • 创建子进程时,将父进程的 虚拟内存物理内存 映射关系复制到子进程中,并将内存设置为只读(设置为只读是为了当对内存进行写操作时触发 缺页异常)。
  • 当子进程或者父进程对内存数据进行修改时,便会触发 写时复制 机制:将原来的内存页复制一份新的,并重新设置其内存映射关系,将父子进程的内存读写权限设置为可读写。

写时复制 过程如下图所示:

img

当创建子进程时,父子进程指向相同的 物理内存,而不是将父进程所占用的 物理内存 复制一份。这样做的好处有两个:

  • 加速创建子进程的速度。
  • 减少进程对物理内存的使用。

如上图所示,当父进程调用 fork 创建子进程时,父进程的 虚拟内存页M 与子进程的 虚拟内存页M 映射到相同的 物理内存页G,并且把父进程与子进程的 虚拟内存页M 都设置为只读(因为设置为只读后,对内存页进行写操作时,将会发生 缺页异常,从而内核可以在缺页异常处理函数中进行物理内存页的复制)。

,对内存页进行写操作时,将会发生 缺页异常,从而内核可以在缺页异常处理函数中进行物理内存页的复制)。

当子进程对 虚拟内存页M 进行写操作,便会触发 缺页异常(因为已经将 虚拟内存页M 设置为只读)。在缺页异常处理函数中,对 物理内存页G 进行复制一份新的 物理内存页G',并且将子进程的 虚拟内存页M 映射到 物理内存页G',同时将父子进程的 虚拟内存页M 设置为可读写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小颜-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值