fork() 和 vfork() 的区别

17 Mar 2025 | 5 分钟阅读

fork()vfork() 都是创建新进程的系统调用。新进程与调用 fork()vfork() 的进程相似。fork() 的使用允许两个进程同时执行。另一方面,vfork() 系统调用会挂起父进程的执行,直到子进程完成其执行过程。

在本文中,您将了解 fork() 和 vfork() 函数之间的区别。但在讨论区别之前,您必须了解 fork() 和 vfork() 函数。

什么是 fork()?

fork() 系统调用主要用于创建新进程。子进程是由 fork() 系统调用创建的新进程,父进程是由 fork() 系统调用触发的进程。子进程的代码与其父进程的代码相似。当创建子进程时,父进程和子进程都从 fork() 之后的下一条语句开始执行,并且两个进程并发执行。

父进程和子进程有不同的地址空间。因此,当其中一个进程更改代码中的语句或变量时,另一个进程的代码不会反映出来。例如,如果子进程更改了代码,它不会影响父进程。

一些子进程在创建后可能会立即调用 exec() 函数。系统函数 exec() 用其参数中定义的程序替换当前进程。之后,子进程的独立地址空间将变得无用,并且包含写时复制函数。写时复制函数允许父进程和子进程共享相同的地址空间。如果每个进程写入地址空间的页面,则会创建一个地址空间的副本,以使两个进程能够独立运行。

什么是 vfork()?

vfork() 是另一个用于创建新进程的系统调用。子进程是由 vfork() 系统调用创建的新进程,而父进程是使用 vfork() 系统调用的进程。子进程的代码与其父进程的代码相似。由于子进程和父进程共享相同的地址空间,因此子进程会挂起父进程的执行,直到子进程完成其执行。

子进程和父进程都共享相同的地址空间。如果其中一个进程更改了代码,那么另一个进程(共享相同页面)就会看到这种更改。假设父进程修改了代码;这将反映在子进程的代码中。

vfork() 系统调用不会为父进程和子进程创建独立的地址空间。因此,它应该在子进程创建后立即使用 exec() 函数的情况下使用。这样就不会浪费地址空间,这是创建进程最有效的方法。vfork() 系统调用不支持写时复制。

fork() 和 vfork() 的主要区别

Difference between fork() and vfork()

fork()vfork() 之间存在许多主要区别。fork() 和 vfork() 之间的一些主要区别如下:

  1. fork() 创建的子进程的内存空间与父进程不同。相反,vfork() 系统调用创建的子进程使用与其父进程相同的地址空间。
  2. 由于父进程和子进程的内存空间是独立的,因此一个进程所做的任何修改都不会影响另一个进程的页面。另一方面,由于父进程和子进程都共享相同的内存地址,因此任何一个进程所做的任何更改都会反映在地址空间中。
  3. 当子进程修改地址空间中的页面时,由于地址空间不同,父进程看不到。相反,当子进程更改地址空间中的页面时,父进程可以看到,因为它们使用相同的地址空间。
  4. fork() 系统调用创建的子进程与父进程并发运行。相反,vfork() 系统调用创建的子进程会挂起父进程的执行,直到子进程完成。
  5. 作为替代方案,fork() 系统调用使用写时复制,允许子进程和父进程共享相同的地址空间,直到其中一个更新页面。相反,vfork() 系统调用不使用写时复制。
  6. 在 fork() 系统调用中,子进程不会挂起父进程的执行。相反,vfork() 系统调用会挂起父进程的执行。
  7. fork() 系统调用存在地址空间浪费。相反,vfork() 系统调用没有地址空间浪费。
  8. fork() 系统调用在进程中被广泛使用。相反,vfork() 系统调用使用较少。

fork() 和 vfork() 系统调用的逐项比较

在这里,您将学习 fork() 和 vfork() 系统调用的逐项比较。fork() 和 vfork() 系统调用之间的一些主要区别如下:

特点fork()vfork()
基本功能在 fork() 系统调用中,两个进程都有独立的地址空间。在 vfork() 系统调用中,子进程和父进程都使用相同的地址空间。
执行在 fork() 中,子进程和父进程都同时执行。在 vfork() 中,父进程会一直暂停,直到子进程完成执行。
写时复制作为替代方案,fork() 系统调用使用写时复制,允许子进程和父进程共享相同的地址空间,直到其中一个更新页面。vfork() 系统调用不使用写时复制。
修改当子进程更改地址空间中的页面时,由于地址空间不同,父进程看不到。当子进程更改地址空间中的页面时,父进程可以看到,因为它们使用相同的地址空间。
浪费fork() 系统调用存在地址空间浪费。vfork() 系统调用没有地址空间浪费。
二手fork() 系统调用在进程中被广泛使用。vfork() 使用较少。
挂起在 fork() 系统调用中,子进程不会挂起父进程的执行。vfork() 系统调用会停止父进程的执行。

结论

fork() 和 vfork() 函数都是系统调用。两个系统都创建了一个与调用 fork() 或 vfork() 的进程相似的新进程。当创建子进程时,父进程和子进程都从 fork() 之后的下一条语句开始执行,并且两个进程并发执行。相反,在 vfork() 系统调用中,子进程会暂停父进程的执行,直到子进程完成其执行,因为子进程和父进程都使用相同的地址空间。