首页 文章

如何复制写作工作

提问于
浏览
2

假设我们有一个父进程,内存中存储了一些任意数量的数据,我们使用fork来生成子进程 . 我理解为了让操作系统在写入时执行复制,包含我们正在修改的数据的内存中的某个页面将设置其只读位,并且操作系统将使用在子项尝试时将导致的异常修改数据以将整个页面复制到内存中的另一个区域,以便孩子获得它自己的副本 . 我不明白的是,如果内存中的特定部分被标记为只读,那么数据最初所属的父级也不能修改数据 . 那么整个方案如何运作呢?即使父母本身试图修改数据,父母是否会失去其数据的所有权并且必须执行写入时的复制?

2 回答

  • 4

    是的,如果任一进程写入COW页面,则会触发页面错误 .

    在页面错误处理程序中,如果页面应该是可写的,它会分配一个新的物理页面并执行 memcpy(newpage, shared_page, pagesize) ,然后更新出现故障的页面表,以将新页面映射到该虚拟地址 . 然后返回用户空间以重新运行存储指令 .

    这是像 fork 这样的胜利,因为一个进程通常会在触摸通常一页(堆栈内存)之后立即进行 execve 系统调用 . execve destroys all memory mappings for that process, effectively replacing it with a new process. 父母再次拥有每个页面的唯一副本 . (除了已经写入时复制的页面,例如,使用 mmap 分配的内存通常是COW映射到零的单个物理页面,因此读取可以在L1d缓存中命中) .

    智能优化将 fork 实际复制包含堆栈顶部的页面,但仍然为所有其他页面执行惰性COW,假设子进程通常会立即 execve 并因此删除其对所有其他页面的引用其他页面 . 但是,在父级中仍然需要TLB无效才能暂时将所有页面翻转为只读和返回 .

  • 0

    某些UNIX实现在两者之间共享程序文本,因为无法修改 . 或者,子节点可以共享父节点的所有内存,但是在这种情况下,内存是共享的写时复制,这意味着只要两者中的任何一个想要修改部分内存,就会首先明确复制该块内存 . 确保修改发生在私有内存区域 . 摘录自:现代操作系统(第4版),Tanenbaum

    enter image description here

相关问题