linux 下写一个复制函数,Linux写时复制原理

原标题:Linux写时复制原理

本文转载自 Linux内核那些事

来源:xusong.lie

链接:http://mp.weixin.qq.com/s/h4xp7gcupExHUUCJ6PA6VA

当调用fork()系统调用创建一个子进程时,Linux并不会为子进程创建新的物理内存空间,而是公用父进程的物理内存。这是因为Linux的内核开发者觉得,调用者调用fork()系统调用后会立刻调用exec()系统调用执行新的程序,这样旧的物理内存内容就没有什么作用了(因为新的程序与旧的程序完全没有关联),所以为子进程复制父进程的物理内存内容是一件徒劳无功的事情。

所以Linux的做法就是:父子进程共用同一物理内存。如下图:

f9c56e438024ac27cb2a6bdd13cd7636.png

但操作系统的要求是:进程之间的内存应该要独立,就是读写A进程的内存空间不应该影响B进程的内存内容。读操作是不会改变内存中的内容,所以对于读操作来说,共享物理内存是安全的。但是对于写操作就不一样,如果父子进程共用了相同的物理内存,那么对子进程的内存进行写操作同时会影响到父进程,所以违反了操作系统的要求。

Linux的解决方案是:把共用的物理内存设置为只读,因为读操作不会改变内存的内容,所以对于父子进程都是允许的。而当父子进程其中一个进行写操作时,因为内存被设置为只读,所以CPU会触发 “page fault” 的错误,从而调用内核的do_page_fault()函数。而do_page_fault()函数又会调用do_wp_page()函数去进行复制父进程内存的内容。

do_wp_page()函数先进行一些安全监测,然后调用__do_wp_page()函数做最后的复制操作。去掉一些监测后,__do_wp_page()函数的代码如下图:

d76e1a45d24d32143dbc1fa4624698e6.png

__do_wp_page()首先会申请一块新的物理内存,然后复制旧的物理内存页的内容到新的物理内存也中,然后设置虚拟内存与物理内存的映射关系。最后把父子进程的物理内存设置可读写,这样父子进程相同的虚拟内存都指向不同的物理内存,所以达到进程之间内存隔离的目的。如下图:

责任编辑:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值