Linux之fork、vfork、写时复制
一、传统的fork()
传统的fork()系统调用直接把所有的资源复制给新创建的进程。这种实现过于简单并且效率低下,因为它拷贝的数据或许可以共享。更糟糕的是,如果新进程打算立即执行一个新的映像,那么所有的拷贝都将前功尽弃。
步骤:
· 为子进程的页表分配页面
· 为子进程的页分配页面
· 初始化子进程的页表
· 把父进程的页复制到子进程相应的页中
现在有一个父进程P1,这是一个主体,那么它是有灵魂也有身体的。现在在其虚拟地址空间(有相应的数据结构)上有:正文段,数据段,堆,栈这四个部分,相应的,内核要为这四个部分分配各自的物理块。即:正文段块,数据段块,堆块,栈块。至于如何分配,这是内核去做的事,参考内存管理之段式结构。
二、Linux的fork()
Linux的fork()使用写时拷贝(copy-on-write)页实现。写时拷贝(COW)是一种可以推迟甚至避免拷贝数据的技术。内核此时并不复制整个进程的地址空间,而是让父子进程共享同一个地址空间。只有在需要写入的时候才会复制地址空间,从而使各个进程拥有各自的地址空间。也就是说,资源的复制是在需要写入的时候才会进行,在此之前,只有以只读方式共享。
fork()的实际开销就是复制父进程的页表以及给子进程创建一个进程描述符。
三、Linux的vfork()
这个做法更加激进,内核连子进程的虚拟地址空间结构也不创建了,直接共享了父进程的虚拟空间,当然了,这种做法就顺水推舟的共享了父进程的物理空间。