fork之写时拷贝技术

来源:互联网 发布:js获取自定义属性data 编辑:程序博客网 时间:2024/06/05 03:47
       现在大家对fork的主要功能应该很清楚了,我们上一篇也讨论到了,fork函数之后子进程的堆区、栈区和全局数据都是不共享,那我们是不是认为其实父进程每次fork产生一个子进程时,子进程都拷贝了一个父进程的内存空间呢?这个问题就是我们这篇博客要解决的问题。
       fork之后经常会和一个exec函数一起使用,exec的详细介绍我们下一篇博客将会写出,我们现在暂时可以了解它就是替换当前程序映像,执行其他的程序。而且大多时候都是这样,当我们创建一个新的进程的时候,我们更多的是希望它去完成的是不同的功能。所以如果我们父进程原来内存空间很大,我们再把它重新拷贝一份,第一浪费cpu的时间,效率降低了,因为拷贝是需要花时间的;第二,就是我们浪费了内存,如果说子进程拷贝过去只是想完成读取数据的功能,那我们拷贝是不是多余呢,直接让子进程和父进程共享内存空间就好了,反正子进程不会修改数据;还有一个情况就是如果我们父进程内容很多,cpu辛辛苦苦拷贝过去,结果发现我们fork一个新进程的目的是想要要它执行另外的程序,执行不同的功能,那我们又要将新程序的数据再拷贝过去覆盖原来内存上cpu辛辛苦苦拷贝过来的数据,这岂不是辛辛苦苦大半年,一下回到解放前。所以我们聪明的操作系统设计人员才不会让这种低效又浪费内存的事情发生。我们fork实现大多采取的方法都是写时拷贝技术,也就是说fork之后,其实子进程并没有真正把父进程的内存数据拷贝一份,而是让子进程和父进程共享同一个存储区域。不过操作系统会将这片区域设置为只读,当父子进程中任何一个进程修改了其中的数据,操作系统就会发出一个缺页中断,然后由操作系统内核将修改的数据所在的页复制一份,分配给数据的进程,并且更新它的页表信息,只将修改数据的进程在拷贝后的页的权限设置为读写。文字叙述可能有点枯燥,大家可以看一下下面的图。


原创粉丝点击