我希望在 Google 上找到这四个之间的区别,并且我预计会有大量关于此的信息,但是这四个调用之间确实没有任何可靠的比较。
我开始尝试编译一种基本的概览,看看这些系统调用之间的差异,这就是我得到的。所有这些信息是否正确/我是否遗漏了任何重要的信息?
Fork
:fork 调用基本上复制了当前进程,几乎在所有方面都相同(并非所有内容都被复制,例如,某些实现中的资源限制,但想法是创建为关闭副本尽可能)。
新进程(子)获得不同的进程 ID(PID),并将旧进程(父)的 PID 作为其父 PID(PPID)。因为这两个进程现在运行的代码完全相同,所以它们可以通过 fork 的返回码来判断哪个是哪个 - 子进程得到 0,父进程得到子进程的 PID。当然,这就是全部,假设 fork 调用有效 - 如果没有,则不会创建子节点并且父节点会收到错误代码。
Vfork
: The basic difference between vfork()
and fork()
is that when a new process is created with vfork()
, the parent process is temporarily suspended ,子进程可能会借用父进程的地址空间。这种奇怪的情况一直持续到子进程退出或调用 execve()
,此时父进程继续。
这意味着一个 vfork()
的子进程必须小心避免意外修改父进程的变量。特别是子进程不能从包含 vfork()
调用的函数返回,也不能调用 exit()
(如果需要退出,应该使用 _exit()
; 实际上,对于正常的孩子也是如此 fork()
)。
Exec
: exec 调用是一种基本上用新程序替换整个当前进程的方法。它将程序加载到当前进程空间并从入口点运行它。 exec()
用函数指向的可执行文件替换当前进程。除非出现 exec()
错误,否则控制永远不会返回到原始程序。
Clone
: clone()
作为 fork()
创建一个新进程。与 fork()
不同,这些调用允许子进程与调用进程共享其部分执行上下文,例如内存空间、文件描述符表和信号处理程序表。
当使用 clone()
创建子进程时,它执行函数应用程序 fn(arg) (这与 fork()
不同,其中从原始点继续在子进程中执行 fork()
调用。) fn 参数是一个指向函数的指针,子进程在其执行开始时调用该函数。 arg 参数被传递给 fn 函数。
当 fn(arg) 函数应用程序返回时,子进程终止。 fn 返回的整数是子进程的退出代码。子进程也可以通过调用 exit(2)
或在收到致命信号后显式终止。
得到的信息:
- fork 和 exec 的区别
- http://www.allinterview.com/showanswers/59616.html
- http://www.unixguide.net/unix/programming/1.1.2.shtml
- http://linux.about.com/library/cmd/blcmdl2_clone.htm
感谢您抽时间阅读 ! :)
原文由 user476033 发布,翻译遵循 CC BY-SA 4.0 许可协议
vfork()
是一个过时的优化。在良好的内存管理之前,fork()
制作了父内存的完整副本,因此非常昂贵。因为在许多情况下fork()
后面跟着exec()
,它会丢弃当前的内存映射并创建一个新的映射,这是不必要的开销。如今,fork()
不复制内存; it’s simply set as “copy on write”, sofork()
+exec()
is just as efficient asvfork()
+exec()
.clone()
是fork()
使用的系统调用。使用一些参数,它创建一个新进程,使用其他参数,它创建一个线程。它们之间的区别只是哪些数据结构(内存空间、处理器状态、堆栈、PID、打开的文件等)是共享的或不共享的。