一尘不染

fork(),vfork(),exec()和clone()之间的区别

linux

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

我着手尝试汇编一下这些系统调用之间的区别的基本概况,这就是我得到的。所有这些信息是否正确/我是否缺少任何重要信息?

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

新进程(子进程)获得不同的进程ID(PID),并将旧进程(父进程)的PID作为其父进程PID(PPID)。因为这两个进程现在运行的是完全相同的代码,所以它们可以通过fork的返回码来确定哪个是哪个-
子代为0,父代为子代的PID。当然,这一切都假设fork调用有效-如果不成功,则不会创建任何子代,并且父代会得到错误代码。

Vfork:vfork和fork之间的基本区别在于,当使用vfork()创建新进程时,父进程会暂时挂起,子进程可能会借用父进程的地址空间。这种奇怪的状态一直持续到子进程退出或调用execve(),此时父进程继续。

这意味着vfork()的子进程必须小心,以免意外修改父进程的变量。特别是,子进程一定不能从包含vfork()调用的函数中返回,也一定不能调用exit()(如果需要退出,则应该使用_exit();实际上,对于子进程也是如此)普通fork()的形式。

Exec :exec调用是一种用新程序基本上替换整个当前过程的方法。它将程序加载到当前进程空间并从入口点运行它。exec()将当前进程替换为函数所指向的可执行文件。除非有exec()错误,否则控制权永远不会返回到原始程序。

Clone :克隆(作为分叉)创建一个新进程。与fork不同,这些调用允许子进程与调用进程共享其执行上下文的各个部分,例如内存空间,文件描述符表和信号处理程序表。

使用克隆创建子进程时,它将执行功能应用程序fn(arg)。(这与fork不同,fork从原始fork调用的位置开始在子级中继续执行。)fn参数是指向该函数的指针,该函数在子进程执行开始时即被调用。arg参数传递给fn函数。

当fn(arg)函数应用程序返回时,子进程终止。fn返回的整数是子进程的退出代码。子进程也可以通过调用exit(2)或在接收到致命信号后显式终止。

信息表:

感谢您抽时间阅读 !:)


阅读 514

收藏
2020-06-02

共1个答案

一尘不染

  • vfork()是过时的优化。在进行良好的内存管理之前,fork()请先复制父代的内存,因此非常昂贵。因为在很多情况下,a fork()之后是exec(),它会丢弃当前的内存映射并创建一个新的内存映射,因此这是不必要的开销。如今,fork()不复制内存。它只是设置为“写时复制”,因此fork()+ exec()vfork()+ 一样有效exec()

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

2020-06-02