Linux0.11共享内存机制
Linux操作系统设计的精妙之处简直让人赞叹不已,不得不佩服Linus这个天才!
共享内存也是一种节约内存使用、减小系统硬件开销的机制,他基于写时复制。
设想这样一个场景:一个可执行文件x.bin被加载到内存中以进程A的形式首次运行,由于某些原因x.bin只是部分被加载,剩下的部分还在硬盘里。当执行到逻辑地址address时由于缺页,引发缺页异常,剩下的部分从硬盘被加载到内存中,进程A得以继续运行。
在A还没退出时,shell再次执行了x.bin,此时x.bin以进程B的形式运行,同样还是运行到逻辑地址address发生了缺页异常,这次异常处理函数首先发现竟然还有A进程也在运行x.bin,于是去查找A的进程空间里面有没有B缺少的页面,结果找到了,于是直接将这一页映射到B的页表项中,B又可以继续运行。
以上就是共享内存的过程,可以看到共享内存发生在缺页的时候。
mm/memory.c
如果进程中还未加载任何可执行文件或者缺页发生在可执行文件数据段以外(这里数据段指的是可执行文件中的数据段,是静态的,包括了代码段和数据段)比如用户堆栈,则重新申请一块空闲页面并映射到线性地址address处。
如果是在数据段内发生了缺页则进行内存共享。
mm/memory.c
如果共享内存失败则申请一个空闲页面,并把所缺页面从磁盘中读入刚申请的页面,把新页面映射到address处然后继续执行。这就是整个的缺页异常处理流程。
他首先是去尝试共享,共享不成功就从磁盘中读,不失为一种高效的方法!
mm/memory.c
share_page函数在尝试共享之前要检查当前进程是否满足共享的要求,即有另一个进程也在运行同一个可执行文件。如果条件满足就去执行try_to_share这个真正的共享操作。
mm/memory.c
try_to_share接受两个参数,address相对于code_start的偏移,也就是发生缺页的地方,p是可以提供共享的进程。
mm/memory.c
检查目标进程对应的页面是否适合共享,如果页面已脏或者超出用户内存范围则退出。
mm/memory.c
最后将共享页面设置为只读,将共享页面保护起来,将共享页面映射到缺页地址处,并且将共享页面的引用数+1。共享完成,如果发生对共享页面的写操作,那就是写时复制了,前面已经介绍过。
- End -
看雪ID:极目楚天舒
https://bbs.pediy.com/user-741085.htm
本文由看雪论坛 极目楚天舒 原创
转载请注明来自看雪社区
热门图书推荐:
征题正在火热进行中!
(晋级赛Q1即将于3月10日开启,敬请期待!)
推荐阅读
公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com