fork()
的代码。我们为什么需要使用 fork()
,它的目的是什么?首先需要了解什么是fork()系统调用。让我来解释一下。
fork()系统调用创建父进程的完全副本,它复制了父进程的堆栈、堆、初始化数据、未初始化数据,并与父进程共享只读模式的代码。
fork()系统调用基于写时复制原则复制内存,也就是说,当需要复制时,子进程在虚拟内存中创建一个页面。
现在我们来看看fork()的目的:
在Unix系统中,fork()和exec()函数都可以用于启动新进程,但是它们的原理不同。关于为什么要使用fork()而不是仅使用exec()函数的解释可以在unix stack exchange上类似问题的答案中找到。
实际上,由于fork()会复制当前进程,所有可能的进程选项都会默认建立,因此程序员不必提供它们。
相比之下,在Windows操作系统中,程序员必须使用CreateProcess函数,这更加复杂,并需要填充各种结构来定义新进程的参数。
因此,总的来说,使用fork()创建新进程比exec()更简单。
fork()
用于生成一个子进程。通常它被用于类似的线程情况,但是有些区别。不像线程一样,fork()
会创建整个独立的进程,这意味着当调用fork()
时,子进程和父进程虽然在某些情况下是彼此的直接副本,但它们是完全分离的,不能访问对方的内存空间(除非你去尝试访问另一个程序的内存所需的正常麻烦)。
一些服务器应用仍然使用fork()
,主要是那些运行为root用户并在处理用户请求之前降低权限的*NIX机器上的应用。还有一些其他用例,但现在大多数人已经转向了多线程。
Fork()系统调用用于创建一个子进程。它是父进程的完全副本。Fork会从父进程复制栈段、堆段、数据段、环境变量和命令行参数。
Fork() 是一种创建具有共享内存状态副本的另一个进程的方法。它之所以如此工作,是因为在时间分片主机系统中实现良好线程能力时,这是最小的可能变化。另外,程序需要非常少的修改就可以成为多进程,fork() 只需要在适当的位置添加即可,这相当优雅。基本上,fork() 是最轻松的方法。
最初,它确实需要复制整个父进程的内存空间。随着虚拟内存的出现,它已经被改进和优化,采用写时复制机制来避免实际复制任何内存。
然而,现代系统现在允许创建实际线程,它们只是共享父进程的实际堆。使用现代的多线程编程范式和更先进的语言,值得怀疑 fork() 是否提供任何真正的好处,因为 fork() 实际上防止进程直接通过内存进行通信,并强制它们使用较慢的消息传递机制。