linux - fork()、vfork()、exec()和clone()的区别

我希望在 Google 上找到这四个之间的区别,我预计会有大量关于这方面的信息,但是这四个调用之间确实没有任何可靠的比较。

我开始尝试编译一种基本的概览,看看这些系统调用之间的差异,这就是我得到的。所有这些信息是否正确/我是否遗漏了任何重要的信息?

Fork :fork 调用基本上复制了当前进程,几乎在所有方面都相同(并非所有内容都被复制,例如,某些实现中的资源限制,但想法是创建尽可能接近副本)。

新进程(子进程)获得不同的进程 ID(PID),并以旧进程(父进程)的 PI​​D 作为其父进程 PID(PPID)。因为这两个进程现在运行的代码完全相同,所以它们可以通过 fork 的返回码来判断哪个是哪个 - 子进程得到 0,父进程得到子进程的 PID。这就是全部,当然,假设 fork 调用有效 - 如果没有,则不会创建子节点并且父节点会收到错误代码。

Vfork:vfork()fork()的基本区别在于当使用vfork创建新进程时(),父进程暂时挂起,子进程可能会借用父进程的地址空间。这种奇怪的情况一直持续到子进程退出,或者调用 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) 或在收到致命信号后显式终止。

信息来自:

  • Differences between fork and 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

感谢您抽出宝贵时间阅读本文! :)

最佳答案

  • vfork()是一个过时的优化。在良好的内存管理之前,fork()制作了 parent 内存的完整副本,因此非常昂贵。因为在许多情况下 fork()紧随其后的是 exec() ,它会丢弃当前的内存映射并创建一个新的映射,这是不必要的开销。如今,fork()不复制内存;它只是设置为“写时复制”,所以fork() + exec()vfork() 一样有效+ exec() .

  • clone()fork() 使用的系统调用.使用一些参数,它创建一个新进程,使用其他参数,它创建一个线程。它们之间的区别只是哪些数据结构(内存空间、处理器状态、堆栈、PID、打开的文件等)是共享的。

https://stackoverflow.com/questions/4856255/

相关文章:

linux - 遍历带有空格的文件列表

python - 访问列表的多个元素知道它们的索引

linux - `set -x` 有什么作用?

linux - 如何在文件开头插入文本?

python - 如何在正则表达式中使用变量?

python - 在 TensorFlow 中,Session.run() 和 Tensor.eva

linux - 增加 Linux 中 TCP/IP 连接的最大数量

linux - 如何更改 Linux 中打开文件的数量限制?

python - 如何并行化一个简单的 Python 循环?

python - 将 numpy dtypes 转换为原生 python 类型