552 字
3 分钟
什么是写时复制?fork 和私有映射如何利用 COW
写时复制(Copy-on-Write,COW)是一种延迟复制策略:多个执行主体暂时共享同一份只读物理页面;当其中一个尝试写入时,处理器触发保护异常,内核分配新页面、复制内容、更新该主体的页表权限,再重新执行写操作。这样只有真正被写到的页面才复制,避免一开始复制大量最终不会修改的数据。
fork() 常采用 COW:父子进程获得逻辑上独立的私有地址空间,最初可共享物理页;任一方写入时才分离出私有副本。COW 并不意味着父子进程永远共享数据,也不意味着 fork 完全没有成本:仍需建立进程结构、复制或调整页表,并在写时付出缺页处理和复制页面的成本。
文件 MAP_PRIVATE 映射也使用类似的私有写入语义;共享映射则用于让修改对其他映射者可见。COW 依赖页权限和内核异常处理,是实现优化,不会改变应用对私有映射隔离语义的理解。
COW 页面上的引用计数和映射权限必须正确维护。若页面只有一个使用者,内核有时可直接恢复写权限而不复制;若多个使用者共享,则需要复制。大页面、透明大页和硬件特性会改变实际拆分与成本,因此不能假设每次写都恰好复制固定大小的一页。
常见追问
Q:fork 后父进程修改变量,子进程会看到吗?
A:普通私有内存不会。写入触发 COW 后,父子进程各自拥有修改后的私有页;显式共享内存等区域例外。
Q:COW 是零拷贝吗?
A:不是。它延迟并减少不必要复制,但发生写入时仍要复制页面;创建页表和缺页处理也有成本。
Q:COW 为什么要把共享页设为只读?
A:这样任一方写入时会触发异常,内核能识别共享页面并执行分离复制,维持私有地址空间语义。
什么是写时复制?fork 和私有映射如何利用 COW
https://blog.xqcherry.top/posts/interview/operating-system/copy-on-write/ 目录