GNU/Linux上pthread和fork的区别

51

在Linux中,pthread和fork的基本区别是实现方式和调度方式不同(如果有变化的话)。

我对两个类似的程序运行了strace,一个使用pthread,另一个使用fork,最后都使用了不同的参数进行了clone()系统调用。因此,我猜想在Linux系统上,这两者本质上是相同的,但是pthread在代码中更容易处理。

有人能给出详细解释吗?

编辑:也可以参考相关问题(链接)


我在这里列出了一些有用的区别:https://dev59.com/6XA65IYBdhLWcg3w1SRC#3705919 - Matt Joiner
3个回答

84
在C语言中,有一些不同之处:
fork()
- 目的是创建一个新的进程,该进程成为调用者的子进程 - 两个进程都将执行fork()系统调用后的下一条指令 - 为父进程和子进程分别创建了计算机的地址空间、代码和堆栈的两个相同副本。
把fork想象成一个人;分叉会导致你的程序(进程)的克隆,它正在运行复制的代码。

pthread_create()

  • 目的是在程序中创建一个新的线程,该线程具有与调用者相同的进程

  • 同一进程内的线程可以使用共享内存进行通信。(小心!)

  • 第二个线程将共享数据、打开文件、信号处理程序和信号处理方式、当前工作目录、用户和组ID。但新线程将拥有自己的堆栈、线程ID和寄存器。

继续类比;当创建一个新线程时,您的程序(进程)就像长出了第二只手臂,连接到同一个大脑。


性能差异

默认情况下,分叉进程不与父进程共享内存空间和其他资源(例如文件句柄),而在同一进程中的线程共享这些资源。在线程间通信方面,共享内存可以更高效快速,但需要进行仔细同步以防止竞态条件。

由于同一进程中的线程共享内存空间,它们比每个拥有自己内存空间的分叉进程更节省内存。


10
我认为您指出了最重要的区别,即共享内存,而 fork 将有自己的生命。 (+1 for pointing at the most important difference in my opinion: memory is shared with the process, whereas fork will live its own life.) - Matthieu
2
生长第二只手臂是一个很好的比喻! - Sid Sahay
1
很棒的帖子!你介意加一句关于调用forkpthread_create时性能差异的句子吗? - Felix Quehl
@FelixQuehl,我试过了。你觉得怎么样?也许其他人可能有更多的低层次知识。 - Gabriel Fair

15

在Linux中,系统调用clone可以克隆一个任务,并且可以配置共享级别。 fork()调用clone(最小共享),而pthread_create()调用clone(最大共享)。 由于需要复制表和为内存创建COW映射,因此fork的成本略高于pthread_create。


7

您应该查看clone手册。

特别是,它列出了所有可能的克隆模式以及它们如何影响进程/线程、虚拟内存空间等等...

您说“在代码中处理线程更容易”:这是非常有争议的。编写无错误、无死锁的多线程代码可能是一项相当大的挑战。有时候,使用两个独立的进程可以使事情变得更简单。


那么,最终Linux会以相同的方式处理pthread和fork,并以相同的方式进行调度吗? - srinathhs
一般而言,是的。这并不意味着您不能拥有不同的调度策略,或者特定的调度程序不能将不同的设置应用于线程组与普通进程。 (顺便说一句,“fork”是通过“clone”系统调用实现的。) - Mat
2
这就是上帝创造 Erlang 的原因。 - Farshid Ashouri

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