为什么 fork 和 exec 保留 2 个单独的调用
我了解 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
主要原因可能是
fork()
和exec()
步骤的分离允许使用其他系统调用来完成子环境的任意设置。例如,您可以:...还有更多。如果您要将这些调用组合成一个
spawn()
调用,那么它必须有一个非常复杂的接口,以便能够对子环境的所有这些可能的更改进行编码 - 并且如果您一旦添加了新的设置,就需要更改界面。另一方面,单独的fork()
和exec()
步骤允许您使用普通的系统调用(open()
、>close()
,dup()
,fcntl()
, ...) 在exec()< 之前操作子进程的环境/代码>。新功能(例如
capset()
)很容易支持。The main reason is likely that the separation of the
fork()
andexec()
steps allows arbitrary setup of the child environment to be done using other system calls. For example, you can:...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, separatefork()
andexec()
steps allow you to use the ordinary system calls (open()
,close()
,dup()
,fcntl()
, ...) to manipulate the child's environment prior to theexec()
. New functionality (eg.capset()
) is easily supported.fork 和 exec 做完全不同的事情。
有很多理由只使用一个进程而不使用另一个进程。您可以派生代表您的控制父应用程序执行任务的子进程,例如,这在 UNIX 世界中很常见。例如,您可以为其他一些奇怪的应用程序设置先决条件,然后从启动器应用程序中执行它,而无需使用 fork。
fork and exec do completely different things.
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.
从书稿来看,xv6 是一个简单的、类 Unix 的教学操作麻省理工学院课程 6.828 中使用的系统:
基本上就像咖啡馆下面所说的那样,但提供了一个很好的参考。实现一个简单的 shell 可能会让原因变得非常清楚。
From the draft book, xv6 a simple, Unix-like teaching operating system used in MIT course 6.828:
Basically as caf says below but providing a good reference. Implementing a simple shell would probably make the reasons very clear.
据我所知,最初只有 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.
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.