fork()的目的是什么?

115
在许多 Linux 的程序和 man 手册中,我看到了使用 fork() 的代码。我们为什么需要使用 fork(),它的目的是什么?

163
为了让所有就餐的哲学家都不会挨饿。 - kenj0418
15个回答

2

首先需要了解什么是fork()系统调用。让我来解释一下。

  1. fork()系统调用创建父进程的完全副本,它复制了父进程的堆栈、堆、初始化数据、未初始化数据,并与父进程共享只读模式的代码。

  2. fork()系统调用基于写时复制原则复制内存,也就是说,当需要复制时,子进程在虚拟内存中创建一个页面。

现在我们来看看fork()的目的:

  1. 可以在需要分工的地方使用fork(),例如服务器必须处理多个客户端,因此父进程必须定期接受连接,所以服务器为每个客户端执行读写操作时都会使用fork()。

2

在Unix系统中,fork()和exec()函数都可以用于启动新进程,但是它们的原理不同。关于为什么要使用fork()而不是仅使用exec()函数的解释可以在unix stack exchange上类似问题的答案中找到。

实际上,由于fork()会复制当前进程,所有可能的进程选项都会默认建立,因此程序员不必提供它们。

相比之下,在Windows操作系统中,程序员必须使用CreateProcess函数,这更加复杂,并需要填充各种结构来定义新进程的参数。

因此,总的来说,使用fork()创建新进程比exec()更简单。


1

fork()用于生成一个子进程。通常它被用于类似的线程情况,但是有些区别。不像线程一样,fork()会创建整个独立的进程,这意味着当调用fork()时,子进程和父进程虽然在某些情况下是彼此的直接副本,但它们是完全分离的,不能访问对方的内存空间(除非你去尝试访问另一个程序的内存所需的正常麻烦)。

一些服务器应用仍然使用fork(),主要是那些运行为root用户并在处理用户请求之前降低权限的*NIX机器上的应用。还有一些其他用例,但现在大多数人已经转向了多线程。


2
我不理解“大多数人”已经转向多线程的看法。进程是必不可少的,线程也是如此。没有人从任何一个方面“转移”。在并行编程中,最大和最并发的代码是分布式内存多进程程序(例如MapReduce和MPI)。尽管如此,大多数人会选择OpenMP或某些共享内存范例来处理多核机器,而GPU这些天正在使用线程,但还有很多其他东西。不过,我敢打赌,在这个网站上,更多的编码人员遇到的是服务器端的进程并行,而不是任何多线程的东西。 - Todd Gamblin

0

0

Fork() 是一种创建具有共享内存状态副本的另一个进程的方法。它之所以如此工作,是因为在时间分片主机系统中实现良好线程能力时,这是最小的可能变化。另外,程序需要非常少的修改就可以成为多进程,fork() 只需要在适当的位置添加即可,这相当优雅。基本上,fork() 是最轻松的方法。

最初,它确实需要复制整个父进程的内存空间。随着虚拟内存的出现,它已经被改进和优化,采用写时复制机制来避免实际复制任何内存。

然而,现代系统现在允许创建实际线程,它们只是共享父进程的实际堆。使用现代的多线程编程范式和更先进的语言,值得怀疑 fork() 是否提供任何真正的好处,因为 fork() 实际上防止进程直接通过内存进行通信,并强制它们使用较慢的消息传递机制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接