线程与(分叉)进程

Gre*_*hal 9 process fork thread

Linux 应用程序通常 fork 然后 exec(使用 execve() ),但 Java 应用程序和某些 Apache MPM 使用线程。如果fork,使用fork + exec来生成一个进程,线程的高级版本是什么?JVM 或 Worker MPM 如何产生线程?

V13*_*V13 14

线程和进程背后的想法大致相同:您分叉执行路径。否则线程和进程在内存等方面有所不同。即进程具有不同的 VM 空间,而线程共享拆分之前存在的任何内容。

使用 clone() 调用(man 2 clone)作为线程和分叉工作的基础:

与 fork(2) 不同,clone() 允许子进程与调用进程共享其执行上下文的一部分,例如内存空间、文件描述符表和信号处理程序表。(请注意,在本手册页上,“调用进程”通常对应于“父进程”。但请参阅下面的 CLONE_PARENT 说明。)

clone() 的主要用途是实现线程:在共享内存空间中并发运行的程序中的多个控制线程。

差异来自传递给 clone() 的标志。从手册页可以看出,fork 和 threading 只是 clone() 的一组预定义参数。然而,人们也可以用它来做定制的东西。

  • @0xC0000022L 您错过了 V13 答案的重要部分:“您分叉了执行路径”- 问题是关于线程是如何产生的,而不是线程和进程之间的区别是什么 (4认同)
  • @0xC0000022L 在我看来,您的论点与答案并不矛盾。 (3认同)

mpe*_*ez0 8

大多数非 Unix 多处理操作系统 (OS) 使用“spawn()”调用或类似方法来生成新的 OS 进程或控制流。Spawn() 往往是一个非常复杂的调用,有很多选项和很多开销。Unix 的一项创新是提供一种开销低得多的创建进程的方式——fork()。Unix 通过允许在 spawn() 的另一半之前使用 exec() 进行任意数量的处理来处理 spawn() 的许多必要选项。

随着 Unix 及其变体的使用越来越多,低开销进程创建被发现是有用的,并被使用。事实上,它被使用得如此之多,以至于人们想要以更低开销的方式来创建进程,因此“线程”的想法诞生了。最初,线程完全由原始进程处理(并且像 JVM 这样的程序可能会使用“绿色线程”来做到这一点);但是处理多线程调度很棘手并且经常被错误地处理。因此,有一种更简单的中间线程处理方式,其中操作系统处理调度,但通过(通常)在线程之间共享地址空间可以节省一些开销。

您的问题很难回答,因为有几个不同但相关的概念都是“线程”,而对于详细信息,您需要一个形容词来描述您所引用的概念。另一方面,了解差异可能会引导您找到所需的具体答案。查找诸如“轻量级进程”、“用户线程”和“rfork()”之类的内容以获取更多信息。

  • @Bakuriu - 查找有关构建多处理调度程序、维护公平性、避免饥饿、处理优先级等的许多文章中的任何一篇。正如您所说,实现用户空间线程不是问题。安排非平凡的例子很困难。 (2认同)