在Unix中,每当我们要创建一个新进程时,便会分叉当前进程,并创建一个与父进程完全相同的新子进程。然后我们执行一个exec系统调用,将父流程中的所有数据替换为新流程中的数据。
为什么我们首先创建父流程的副本,而不直接创建新流程?
简而言之,fork
是在Unix中,因为当时它很容易安装到现有系统中,并且伯克利的前身系统已经使用了fork的概念。
摘自Unix分时系统的演进(相关文本已突出显示):
几天之内就设计并实施了现代形式的过程控制。令人惊讶的是,它很容易安装到现有系统中;同时,很容易看到设计中某些稍微不寻常的功能是如何呈现的,因为它们代表了对存在的内容的细微,易于编码的更改。一个很好的例子是fork和exec函数的分离。创建新流程的最常见模型包括指定要执行的流程的程序。在Unix中,分叉的进程将继续与其父进程运行相同的程序,直到执行显式的exec。这些功能的分离当然不是Unix独有的,事实上,它存在于汤普森众所周知的伯克利分时系统中。。仍然可以合理地假设它存在于Unix中,主要是因为可以很容易地实现fork而不改变其他内容。该系统已经处理了多个(即两个)过程。有一个进程表,并且进程在主内存和磁盘之间交换。fork的初始实现只需要
1)扩展过程表
2)添加了一个fork调用,该调用使用已存在的swap IO原语将当前进程复制到磁盘交换区域,并对进程表进行了一些调整。
实际上,PDP-7的fork调用恰好需要27行汇编代码。当然,还需要对操作系统和用户程序进行其他更改,其中一些更改非常有趣且出乎意料。但是,仅仅因为不存在这样的exec,合并的fork-exec就会复杂得多。它的功能已经由外壳使用显式IO执行。
从那篇论文开始,Unix就发展了。fork
其次exec
不再是运行程序的唯一方法。
vfork的创建是为了在新进程打算在该分支之后立即执行exec的情况下提高效率。执行vfork之后,父进程和子进程共享相同的数据空间,并且父进程被挂起,直到子进程执行程序或退出。
posix_spawn在一个系统调用中创建一个新进程并执行一个文件。它带有许多参数,可让您有选择地共享调用者的打开文件,并将其信号处置和其他属性复制到新进程。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句