Copy-on-Write 机制
简介
如果有多个调用者同时请求相同的资源(如内存或磁盘上的数据存储), 他们会共同获得相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本(private copy)给该调用者,而其他调用者所见到的最初的资源仍然保持不变。这过程对其他的调用者都是透明的(transparently)。此作法主要的优点是如果调用者没有修改该资源,就不会有副本(private copy)被创建,因此多个调用者只是读取操作时可以共享同一份资源。
fork 中的 COW
fork 系统调用完成后,那么当父进程或者子进程尝试写共享物理页时,内核将拷贝物理页面
写共享内存页
当父进程 A 或子进程 B 任何一方对这些已共享的物理页面执行写操作时,都会产生页面出错异常(page_fault int14
)中断,会将flags & FAULT_FLAG_WRITE
,然后通过do_page_fault() -> handle_mm_fault() -> handle_pte_fault()
调用链解决这个异常。
static vm_fault_t handle_pte_fault(struct vm_fault *vmf) |
pte_write
会根据 pte_flags(pte) & _PAGE_RW
判断页是否有写保护,这个标记是之前 fork 时 clear 掉的,所以会接着调用do_wp_page
/* |
wp_page_copy 函数主要就是分配一个页面,将旧页面的内容复制到新页面。
至此,父进程子进程各自拥有一块内容相同的物理页面。最后,从异常处理函数中返回时,CPU 就会重新执行刚才导致异常的写入操作指令,使进程继续执行下去。
参考
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Lantern's 小站!
评论