为什么 fork 和 exec 保留 2 个单独的调用

发布于 2024-10-18 23:37:43 字数 214 浏览 0 评论 0原文

我了解 fork、vfork、exec、execv、execp 之间的区别。所以请不要抱怨它。 我的问题是关于unix进程创建的设计。为什么设计者考虑创建 2 个单独的调用( fork 和 exec )而不是保持一个紧密的调用( spawn )。 良好的 API 设计是否是让开发人员能够更好地控制流程创建的一个原因? 是否由于性能原因,我们可以延迟将进程表和其他内核结构分配给子进程,直到写入时复制或访问时复制?

I understand the differences between fork, vfork, exec, execv, execp. So pls dont rant about it.
My question is about the design of the unix process creation. Why did the designers think of creating 2 seperate calls ( fork and exec ) instead of keeping it one tight call ( spawn ).
Was good API design a reason so that developers had more control over process creation?
Is it because of performance reason, so that we could delay allocating process table and other kernel structures to the child till either copy-on-write or copy-on-access?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

心病无药医 2024-10-25 23:37:43

主要原因可能是 fork()exec() 步骤的分离允许使用其他系统调用来完成子环境的任意设置。例如,您可以:

  • 设置任意一组打开的文件描述符;
  • 改变信号掩码;
  • 设置当前工作目录;
  • 设置进程组和/或会话;
  • 设置用户、组和补充组;
  • 设置硬资源和软资源限制;

...还有更多。如果您要将这些调用组合成一个 spawn() 调用,那么它必须有一个非常复杂的接口,以便能够对子环境的所有这些可能的更改进行编码 - 并且如果您一旦添加了新的设置,就需要更改界面。另一方面,单独的 fork()exec() 步骤允许您使用普通的系统调用(open()>close(), dup(), fcntl(), ...) 在 exec()< 之前操作子进程的环境/代码>。新功能(例如capset())很容易支持。

The main reason is likely that the separation of the fork() and exec() steps allows arbitrary setup of the child environment to be done using other system calls. For example, you can:

  • Set up an arbitrary set of open file descriptors;
  • Alter the signal mask;
  • Set the current working directory;
  • Set the process group and/or session;
  • Set the user, group and supplementary groups;
  • Set hard and soft resource limits;

...and many more besides. If you were to combine these calls into a single spawn() call, it would have to have a very complex interface, to be able to encode all of these possible changes to the child's environment - and if you ever added a new setting, the interface would need to be changed. On the other hand, separate fork() and exec() steps allow you to use the ordinary system calls (open(), close(), dup(), fcntl(), ...) to manipulate the child's environment prior to the exec(). New functionality (eg. capset()) is easily supported.

|煩躁 2024-10-25 23:37:43

fork 和 exec 做完全不同的事情。

  • fork() - 复制一个进程
  • exec() - 替换一个进程

有很多理由只使用一个进程而不使用另一个进程。您可以派生代表您的控制父应用程序执行任务的子进程,例如,这在 UNIX 世界中很常见。例如,您可以为其他一些奇怪的应用程序设置先决条件,然后从启动器应用程序中执行它,而无需使用 fork。

fork and exec do completely different things.

  • fork() - duplicates a process
  • exec() - replaces a process

There's plenty of reasons to use one without the other. You can fork off child processes that perform tasks on behalf of your controlling parent app e.g., pretty common in the unix world. And you can e.g. setup the preconditions for some other quirky application and then exec it from your launcher application without ever using fork.

顾北清歌寒 2024-10-25 23:37:43

从书稿来看,xv6 是一个简单的、类 Unix 的教学操作麻省理工学院课程 6.828 中使用的系统

现在应该清楚为什么 fork 和 exec 是单独的调用是个好主意了。因为如果它们是分开的,shell可以fork一个子进程,在子进程中使用open、close、dup来改变标准输入和输出文件描述符,然后exec。不需要对正在执行的程序(在我们的示例中为 cat)进行任何更改。如果将 fork 和 exec 组合成一个系统调用,则 shell 需要一些其他(可能更复杂)的方案来重定向标准输入和输出,或者程序本身必须了解如何重定向 I/O。 p>

基本上就像咖啡馆下面所说的那样,但提供了一个很好的参考。实现一个简单的 shell 可能会让原因变得非常清楚。

From the draft book, xv6 a simple, Unix-like teaching operating system used in MIT course 6.828:

Now it should be clear why it is a good idea that fork and exec are separate calls. Because if they are separate, the shell can fork a child, use open, close, dup in the child to change the standard input and output file descriptors, and then exec. No changes to the program being exec-ed (cat in our example) are required. If fork and exec were combined into a single system call, some other (probably more complex) scheme would be required for the shell to redirect standard input and output, or the program itself would have to understand how to redirect I/O.

Basically as caf says below but providing a good reference. Implementing a simple shell would probably make the reasons very clear.

夏末染殇 2024-10-25 23:37:43

据我所知,最初只有 fork()。但出于性能原因,需要创建 exec(),而不会重新创建将立即被覆盖的内核结构。 <-- 这是错误的。

存在性能问题当一个进程需要共同创建一个不是其自身副本的子进程时。 fork() 复制与进程相关的内核数据,这些数据将立即被 exec() 替换。因此引入了vfork(),它不会复制过多的内核数据和任何进程数据;之后,进程预计会调用类似 exec() 的内容,并且父进程将被挂起,直到子进程执行此操作。不过,请参阅“错误”部分以了解 vfork() 问题的描述。

AFAIK, initially there was only fork(). But performance reasons called for creation of exec() that does not re-create the kernel structures that are going to be immediately overwritten. <-- This is wrong.

There's a performance problem when a process needs co create a child process which is not a copy of itself. A fork() copies process-related kernel data which are going to be immediately replaced by an exec(). Thus vfork() was introduced that does not copy excessive kernel data and any process data; after it, a process is expected to call something exec()-like, and the parent is suspended until the child does so. See 'Bugs' section for description of problems with vfork(), though.

我的鱼塘能养鲲 2024-10-25 23:37:43

fork() 只能用于创建子进程。只能复制父进程。
而 exec() 可用于启动系统上的任何新进程。
我没有看到以上两者有任何相关性。

fork() can only be used for creating a child process.Only replication of parent can be done.
While exec() can be used for starting any new process on the system.
I do not see any correlation above two.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文