对Linux0.11 "内核空间不使用写时复制机制" 本质理解

      一个页面被多个进程共享,每当一个进程产生一次写保护 错误,内核将给进程分配一个新的物理页面,将共享页面的内容复制过来,新的页面将设置为可读写,而共享页面仍然是只读的,只是共享计数减小了。当其他共享进程都产生了一次写保护错误后,共享页面的共享计数减成了1,其实就是被一个进程独占了,但此时该共享页面仍然是只读的,如果独占它的进程对它进行写操作仍然会产生写保护出错。为什么不在共享计数减成了 1 之后就将共享页面置为可写呢?原因很简单,因为系统并不知道最后是哪个页表项指向这个共享页,如果要把它查找出来会有很大的系统开销,这是中断处理程序应当尽量避免的,所以采用了以逸待劳的办法。如果当初共享的页面不属于主内存块,在共享时就没有作共享计数的处理,就不存在共享计数的问题,直接复制就可以了。

      以上这段话是出自Linux0.11内存管理分析的一本书上的,在这个网址下载的:http://oldlinux.org/Linux.old/study/Ref-docs/Linux011-Mem-YuanYi.pdf。基本完全讲述了linux0.11内存管理的内容。之前写过一篇博客分析linux0.11内核些事复制机制:http://blog.csdn.net/yihaolovem/article/details/34204265。现在看来还有很多错误,故重新分析一下对内核写时复制机制的理解。

       写时复制机制,即是先通过系统调用fork使多个进程共享同一个进程的目录表项和页目录项,从而共享同一物理内存(可以这么说吧,准确来说是不对的)。假设有一个物理页面M,通过fork后由进程A、B、C(都是用户进程)共享。假设M一开始属于A。若C要写M,则会产生写时复制,重新在主内存申请一页内存newC替代M(newC页面内的内容完全复制自M)供C使用,此时,M由A、B进程共享使用。此后,进程A要对M进行写操作,又会发生写时复制,重新申请一页内存newA给A使用。这时,M仅由进程B独占了。但是,此时若B进程对M进行写操作,则同样会重新申请newB供B使用。那么,开始的M呢?呵呵,被释放了。因为A B C进程读写M的顺序不一定,所以最后一次写M的进程是不确定的,可能是B(所上如上分析过程),也可能是A,还可能是C。所以正如开头一段话所述,如果要查出最后是谁独占M的,从而改变其页表项的读写位,则要对页目录项表和页表项进行顺序遍历查找,是很费效率的。所以才用了以逸待劳的方法。

       以上就是写时复制机制的全过程。

       但是,对于内核空间来说,却是不同的---内核空间不使用写时复制机制!这也是Linus在其内核代码注释中提到的,一开始很不理解。但读了开头第一段话之后便慢慢地理解了。对于内核空间来说,还是以特殊的进程0和进程1来说。进程0是系统中第一个手工创建的程序,其特殊在其地址空间属于内核空间,也就是说,进程0是内核空间的物理页面。系统通过fork函数产生了进程1,此时进程0和1共享内核物理页面(假设为KM)。但是其特殊就特殊在在fork时,内核针对内核空间是特殊对待的,在fork函数过程中调用的函数copy_page_tables中有这样一段代码:

       if (this_page > LOW_MEM) {
     *from_page_table = this_page;
     this_page -= LOW_MEM;
     this_page >>= 12;
     mem_map[this_page]++;
}

       也就是说,只有对于非内核地址空间的页面,才会将被fork共享的页面所对应的页表项设为只读,从而在最后一次写操作的时候,将源页面释放。而对于内核地址空间的地址共享,只将进程1的页目录的属性设置为只读,而源目录表项(进程0)依然是可读写的。这就导致进程1fork进程0而产生之后,只有进程1对共享的物理页面(内核地址空间)进行写操作的时候才会产生写时复制,为进程1在主内存中申请一页新的物理页面作为独属于进程1的物理页面。而进程0对其共享内存的写操作不会引起写时复制,即KM就好像独属于进程0一样。也正是因为如此,所以要保证在进程1写(拥有独属于自己的内存页面)之前保持KM页面的干净,主要是为了保证进程1的堆栈中不含进程0的多余信息,以免弄乱进程1的堆栈空间。

      总体来说,就是"内核空间不使用写时复制机制"的意思就是,对于内核空间的写操作,并不会去申请新的内存页面,即内核空间这种情况下是可读可写的。

       又写了一篇博客,感觉对这块内容完全理解了,呵呵。

  • 1
    点赞
  • 2
    收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 2

打赏作者

i为伱而搁浅

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值