写时复制(Copy-On-Write, COW) 技术介绍
一、写时复制(Copy-On-Write, COW) 技术介绍
在计算机系统中,往往需要在不同进程之间共享数据,或者对已有的数据进行复制。简单的数据复制会造成大量无效的内存占用和性能低下。为了接触和共享本身已有的数据,同时避免不必要的复制,写时复制 (Copy-On-Write, COW) 技术就形成了。
二、技术发展流程
COW 技术最早的应用可以返回到旧时代的 Unix 系统,那时候的系统当中有一个至关重要的操作 – fork(),用于创建子进程。
在旧有实现中,fork() 会将父进程的整个地址空间全部复制给子进程,这样做性能极低。COW 技术出现后,进程之间共享同样的内存项,直到其中一个进程尝试修改该内存区域时,才将它复制,即 “写时复制”。
图示:fork后的写时复制机制
Before write:
+---------+ +---------+
| Parent | ---> | Memory |
| Child | ---> | Block A |
+---------+ +---------+
After write:
+---------+ +---------+ +----------+
| Parent | ---> | Block A | | Block B | <--- Child (write)
+---------+ +---------+ +----------+
三、COW 技术解决的问题
- 减少不必要的内存占用:共享数据,不再对大量数据立即复制,访问性能和资源使用率更高。
- 提升性能:先创建指向同一地址的指针,但不作任何内容复制,直到实际写操作才执行内容复制,省去了大量输入/输出操作。
- 共享思维:倾向在元数据级别实现尽可能的共享,同时保证安全性,提高开发效率。
四、COW 在操作系统中的应用
1. fork() 和虚拟内存 (VM)
当一个系统调用 fork() 时,不再立即复制全部地址空间,而是为父子进程指向同样的内存项,并将这些项标记为只读 (read-only)。当任意一个进程尝试写入时,系统重新为它分配内存,实现写时复制。
2. 文件系统 (Btrfs, ZFS)
现代文件系统里,如 Btrfs 和 ZFS,支持快照 (snapshot)、克隆 (clone) 等操作,依赖 COW 技术实现无需重复的克隆,直到有内容修改。
3. 内存分配 (如 Linux 中的 mmap())
当使用 mmap() 共享文件内容时,使用 COW 技术可以做到读写分离,对同一内容不再不分彼此的复制。
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
int main() {
int fd = open("file.dat", O_RDONLY);
char* data = mmap(NULL, 4096, PROT_READ, MAP_PRIVATE, fd, 0);
// 读操作共享,写时复制
close(fd);
return 0;
}
