fork和vfork都是用来创建子进程的系统调用函数,本文主要对比了二者的区别。

函数形式

fork 创建一个子进程

#include <unistd.h>
pid_t fork(void);

vfork 创建一个子进程并阻塞父进程

#include <sys/types.h>
#include <unistd.h>
pid_t vfork(void);

区别对比

二者的函数形式十分相似,函数的功能也类似,它们的区别可以归纳为以下几点。

  • fork 创建的子进程拥有与父进程独立的地址空间,而 vfork 创建的子进程与父进程共享地址空间。
  • 因为 vfork 创建的子进程共享了父进程的地址空间,如果子进程对地址空间中的内容进行了修改,则父进程也会受到影响(实际上并不推荐这样做)。
  • 使用 fork 时,父子进程是同时执行的,而 vfork 的父进程会等待子进程执行完成后才会继续执行。
  • fork 会使用copy on write策略以提高效率; vfork 并不会复制地址空间。需要注意的是, fork 的速度仍然会受到父进程使用内存大小影响(详见参考资料3)。

vfork 的应用场景主要是配合 exec 系列函数,如果只在子进程中调用 exec 函数,由于 exec 函数会替换子进程的进程映像(process image),所以也就没有必要复制父进程的地址空间了。使用 vfork 时,父进程会阻塞到子进程的 exec_exit 执行。

if ((pid = vfork()) == 0) {
    execl(..., NULL); /* after a successful execl the parent should be resumed */
    _exit(127); /* terminate the child in case execl fails */
}