`

fork写时复制,复制以页为单位

 
阅读更多

写时复制页面保护机制是一种优化,内存管理器利用它可以节约内存。

当进程为一个包含读/写页面的内存区对象映射了一份写时视图,而并非在映射该视图时创建一份进程私有的拷贝(Hewlett  Packard  OpenVMS操作系统就是这样做的)时,内存管理器将页面拷贝的动作推迟到页面被写入数据的时候。所有现代的UNIX系统也都使用了这项技术。如:2个进程正在共享3个页面,每个页面都被标记为写时复制,但是这2个进程都不打算修改页面上的任何数据。

如果这2个进程中任何一个线程对一个页面执行了写操作,则产生一个内存管理错误。内存管理器看到,此写操作作用在一个写时复制的页面上,所以,它不是将此错误报告为访问违例,而是在物理内存中分配一个新的读/写页面,并且把原始页面中的内容拷贝到新的页面中。同时也更新一下该进程中对应的页面映射信息,使它指向新的页面位置,然后解除异常,从而使得刚才产生错误的那条指令得以重新执行。这一次,写操作成功了。但是,新拷贝的页面现在对于执行写操作的那个进程来说是私有的,对于其它仍然在共享这一写时复制页面的进程来说,它是不可见的。每个往共享页面中写入数据的进程都将获得它自己的私有拷贝。

写时复制的一个应用是:在调试器中实现断点支持。例如:在默认情况下,代码页面在起始时都是只能执行的。然而,如果一个程序员在调试一个程序时设置了一个断点,则调试器必须在代码中加入一条断点指令。它是这样做的:首先将该页面的保护模式改变为PAGE_EXECUTE_READWRITE,然后改变指令流。因为代码页面是所映射的内存区的一部分,所以内存管理器为设置了断点的那个进程创建一份私有拷贝,同时其它进程仍然使用原先未经修改的代码页面。

写时复制是“延迟计算(lazy  evaluation)”这一计算技术(evaluation  technique)的一个例子,内存管理器广泛地使用了延迟计算的技术。延迟计算使得只有当绝对需要时才执行一个昂贵的操作--如果该操作从来也不需要的话,则它不会浪费任何一点时间。

POSIX  子系统利用写时复制来实现  fork 函数,当一个UNIX 应用程序调用fork 函数来创建另一个进程时,新进程所做的第一件事是调用exec 函数,用一个可执行程序来重新初始化它的地址空间。 在fork中,新进程不是拷贝整个地址空间,而是通过将页面标记为写时复制的方式,与父进程共享这些页面。如果子进程在这些页面中写入数据了,则生成一份进程私有的拷贝。如果没有写操作,则2个进程继续共享页面,不会执行拷贝动作。不管怎么样,内存管理器只拷贝一个进程试图要写入数据的那些页面,而不是整个地址空间。

想了解写时复制错误的比率,查看性能计数器:Memory: Write  Copies/Sec   。

分享到:
评论

相关推荐

    qlBitRate:一个 OS X QuickLook 插件,用于在 QuickLook 窗口的标题栏中显示 MP3 文件的比特率(以 kbps 为单位)

    qlBitRate是一个 QuickLook 插件,它将在 QuickLook 窗口的标题栏中显示 MP3 文件的比特率(以 kbps 为单位)和文件名。 这个插件已经过测试,可以在 OS X 10.7-10.10 中使用。 安装 预编译 解压缩文件 将文件移动...

    my-auto-green:从https复制

    点右上角Fork按钮复制本GitHub仓库 在自己的项目中,点上方Actions选项卡进入项目GitHub Actions页面,单击绿色按钮“我了解我的工作流程,继续并启用它们”开启自动提交功能 修改为自己的GitHub的账号和昵称 (任选...

    一个进程池的服务器程序

    由于listenfd是在fork之前就有的,所以所有子进程都可以访问到,不需用到“进程间文件描述符传递”问题; 4,子进程每accept到一个请求都告诉父进程,父进程把请求数加1;子进程没完成一个请求,父进程把请求数减1;...

    philosophical-green

    点右上角使用此模板按钮复制本GitHub仓库, :warning:千万不要Fork,因为fork项目的动态并不会使你变绿 :warning: 在自己的项目中,点上方Actions选项卡进入项目GitHub Actions页面,单击绿色按钮“我了解我的工作...

    auto-green

    点右上角使用此模板按钮复制本GitHub仓库, :warning:千万不要Fork,因为fork项目的动态并不会使你变绿 :warning: 在自己的项目中,点上方Actions选项卡进入项目GitHub Actions页面,单击绿色按钮“我了解我的工作...

    auto-green:我的绿色

    点右上角使用此模板按钮复制本GitHub仓库, :warning_selector:千万不要Fork,因为fork项目的动态并不会使你变绿 :warning_selector: 在自己的项目中,点上方Actions选项卡进入项目GitHub Actions页面,单击绿色按钮...

    my-auto-green

    点右上角使用此模板按钮复制本GitHub仓库, :warning:千万不要Fork,因为fork项目的动态并不会使你变绿 :warning: 在自己的项目中,点上方Actions选项卡进入项目GitHub Actions页面,单击绿色按钮“我了解我的工作...

    自动绿

    点右上角使用此模板按钮复制本GitHub仓库, :warning:千万不要Fork,因为fork项目的动态并不会使你变绿 :warning: 在自己的项目中,点上方Actions选项卡进入项目GitHub Actions页面,单击绿色按钮“我了解我的工作...

    自动绿:自动绿

    点右上角使用此模板按钮复制本GitHub仓库, :warning:千万不要Fork,因为fork项目的动态并不会使你变绿 :warning: 在自己的项目中,点上方Actions选项卡进入项目GitHub Actions页面,单击绿色按钮“我了解我的工作...

    mygit

    使用点右上角使用此模板按钮复制本GitHub仓库, :warning:千万不要Fork,因为fork项目的动态并不会使你变绿 :warning:在自己的项目中,点上方Actions选项卡进入项目GitHub Actions页面,单击绿色按钮“我了解我的...

    auto-green:自动提交,绿油油的体验

    点右上角使用此模板按钮复制本GitHub仓库, :warning:千万不要Fork,因为fork项目的动态并不会使你变绿 :warning: 在自己的项目中,点上方Actions选项卡进入项目GitHub Actions页面,单击绿色按钮“我了解我的工作...

    gh-auto-green:自动保持GitHub提交状态常绿

    使用点右上角使用此模板按钮复制本GitHub仓库, :warning:千万不要Fork,因为fork项目的动态并不会使你变绿 :warning:在自己的项目中,点上方Actions选项卡进入项目GitHub Actions页面,单击绿色按钮“我了解我的...

    Individual-learning

    点右上角 Use this template 按钮复制本 GitHub 仓库,:warning: 千万不要 Fork,因为 fork 项目的动态并不会让你变绿 :warning: 修改 为自己的 GitHub 账号和昵称 (可选) 你可以通过修改 来调整频率 计划任务语法有...

    green_her:可以让你的GitHub保持常绿!!!

    使用点右上角 Use this template 按钮复制本 GitHub 仓库,:warning: 千万不要 Fork,因为 fork 项目的动态并不会让你变绿 :warning:修改 为自己的 GitHub 账号和昵称(可选) 你可以通过修改 来调整频率计划任务语法...

    auto-green:只是对自动绿色的测试

    点右上角 Use this template 按钮复制本 GitHub 仓库,:warning: 千万不要 Fork,因为 fork 项目的动态并不会让你变绿 :warning: 修改 为自己的 GitHub 账号和昵称 (可选) 你可以通过修改 来调整频率 计划任务语法有...

    EveryDay

    使用点右上角使用此模板按钮复制本GitHub仓库, :warning:千万不要Fork,因为fork项目的动态并不会使你变绿 :warning:在自己的项目中,点上方动作选项卡进入项目GitHub动作页面,点击绿色按钮“我了解我的工作流程,...

Global site tag (gtag.js) - Google Analytics