美文网首页
为什么将创建进程的 API 设计为 fork 与 exec 分离

为什么将创建进程的 API 设计为 fork 与 exec 分离

作者: Jamza | 来源:发表于2021-08-22 18:54 被阅读0次

在 Unix 下,为什么会将创建进程的 API 设计为需要 fork 与 exec 两个函数来处理?为什么不将两个函数合并为一个函数,比如 createProcess 这样的函数?

针对此问题,在业界存在一些争论,有些人表示这样的设计是 Unix 哲学,即一个函数只专注一个基本功能,而另一些人则对这样的设计表示怀疑,认为这是早期历史原因造成的,在现代操作系统中这样的设计是落后的。

在《操作系统导论》一书中,作者表示操作系统将创建进程的 API 设计为 fork 与 exec 分离,可以实现一些有趣的功能。比如,在 fork 之后,exec 之前,操作系统可以改变子进程的运行环境,从而实现一些特殊的功能。典型的例子,就是 shell 中的重定向功能,若需要将程序的输出从 stdout 重定向到某个文件,shell 在 fork 之后,首先关闭 stdout,然后打开需要保存输出内容的文件,在 open 系统调用执行时,会选择从 0 开始的最小的文件描述符来使用,此时文件描述符为 0 的 stdout 已经被关闭,则文件描述符 0 将被赋予保存子进程输出内容的文件。shell 随后再调用 exec 执行子进程,这样子进程的输出内容将被重定向到某个文件中,而不是 stdout。

The Evolution of the Unix Time-sharing System 中有一段说明:

A good example is the separation of the fork and exec functions. The most common model for the creation of new processes involves specifying a program for the process to execute; in Unix, a forked process continues to run the same program as its parent until it performs an explicit exec. The separation of the functions is certainly not unique to Unix, and in fact it was present in the Berkeley time-sharing system [2], which was well-known to Thompson. Still, it seems reasonable to suppose that it exists in Unix mainly because of the ease with which fork could be implemented without changing much else. The system already handled multiple (i.e. two) processes; there was a process table, and the processes were swapped between main memory and the disk.

当在编写 Unix 时,Thompson 对 Berkeley time-sharing system 中的 fork 很熟悉,因此自然地将 fork 的实现移植到 Unix 中,而不是采用将 fork+exec 合并实现 API 的方式。当然这是历史,但是这个 fork 接口是常用接口,为了考虑兼容性,这么多年下来,这个 API 得以一直保留至今,所以,fork+exec 这样的设计,也存在一些历史的原因。

还有一种解释,在 Unix 的早期,是没有进程、线程的概念,也没有多任务,在实现 shell 程序时,shell 需要执行其他程序,exec 则直接将 shell 从内存中杀死,执行新的程序,当执行完成返回后,再重新加载 shell,拖慢性能,因此 fork 出现了,在 exec 之前,先复制一份 shell,然后 exec 新的程序,执行完成后,复制的 shell 可以继续执行。因此,fork+exec 是在当年没有多任务概念的情况下,为了解决多任务的需求而产生的。

2019 年有一篇论文,也探讨了这个主题:a fork in the road

相关文章

  • Linux--fork与wait

    fork与exec 在Linux中,都是通过fork与vfork系统调用来创建子进程,并且在fork完之后,通常会...

  • Linux进程管理(二)--fork

    基于Kernel 4.4源码 一. 概述 Linux创建进程采用fork()和exec() fork: 采用复制当...

  • Head First C学习之用fork()+exec()运行子

    用fork()克隆进程 因为当用exec()函数运行新进程来替换当前进程是,原进程将立即终止。 fork()回克隆...

  • Linux进程原语

    Linux进程原语及功能: fork:创建一个新的子进程; exec族(execl、execlp、execle、e...

  • Supervisor的作用与配置

    supervisor supervisor管理进程,是通过fork/exec的方式将这些被管理的进程当作super...

  • supervisor包(进程管理工具)

    supervisor 和nohup 的区别: supervisor管理进程,是通过fork/exec的方式将这些被...

  • Linux进程笔记

    进程创建方式 1 fork函数 2 vfork 3 使用exec函数执行一段程序(了解) 进程的状态就绪/运行/阻...

  • Linux内核简述

    进程 创建 创建进程用fork()函数。fork()为子进程创建新的地址空间并且拷贝页表。子进程的虚拟地址空间...

  • 05-学会几个系统调用:咱们公司能接哪些类型的项目?

    立项服务与进程管理 创建进程的系统调用叫作 fork。在 Linux 里,当父进程调用 fork 创建进程的时候,...

  • [c/c++]6. exec函数

    exec 曾提及用fork函数创建新的子进程后,子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种e...

网友评论

      本文标题:为什么将创建进程的 API 设计为 fork 与 exec 分离

      本文链接:https://www.haomeiwen.com/subject/pcqmbltx.html