Fork
传统方式下,Fork创建一个子进程,并为子进程创建一个父进程地址空间的拷贝。然而,由于许多子进程在创建之后通常马上会执行系统调用exec,所以父进程地址空间的复制可能没有必要,从而造成效率和内存的极大浪费。因此,就产生了一种称为“写时复制”的技术。
写时复制
写时复制允许子进程与父进程在开始时共享同一页面。但这些页面被标记为“写时复制”,即如果任何一个进程需要对页进行写操作,就会创建这个共享页的拷贝。例如,假设子进程试图修改含有部分栈的页,且操作系统能够识别出该页为写时复制页,则操作系统就会创建该页的一个拷贝,并将它映射的子进程的地址空间里。这样,子进程修改的就是其复制的页,而不是父进程的页。采用写时复制技术,只有被进程所修改的页才会复制,而所有非修改的页可为父进程和子进程共享。注意,并不是所有的页都标记为写时复制,只有可能修改的页才需要标记为写时复制,对不能修改的页,如代码页,可谓父进程和子进程所共享。
Vfork(Virtual memory fork)
Vfork不同于写时复制的fork。对于vfork,父进程会挂起,以确保子进程先运行。子进程使用父进程的地址空间。由于vfork不使用写时复制,因此如果子进程修改地址空间的任何页,这些修改在父进程重启时都是可见的。所以,vfork必须小心使用,以确保子进程不会修改父进程的地址空间。Vfork主要用于在进程创建后立即调用exec的情况,这样既没有出现复制页,也不会修改父进程的地址空间,所以是一种很有效的进程创建方法。