绿色线程 vs 非绿色线程

104

我希望了解这些类型的线程提供的优势。

  • 在哪些环境中,绿色线程比非绿色线程更好?一些人说绿色线程对于多核处理器更好。

  • 是否存在任何预期的行为问题。


6
翻译:绿色线程对于多核处理器来说更好的可能性极小,因为它不会使用多个核心。如果绿色线程更好,那么你的程序就不应该使用线程(有时候线程被错误地使用)。 - Peter Lawrey
1
线程在哪些情况下不应该被使用? - user1657170
7个回答

102

Green threads是"用户级线程"。 它们由一个“普通”的用户级进程调度,而不是由内核调度。 因此,它们可用于在不提供该功能的平台上模拟多线程。

特别是在Java的语境下,Green threads已经过时了。 请参阅文章JDK 1.1 for Solaris Developer's Guide。(虽然这是关于Solaris的,但是Green threads不再使用的事实对于常见的平台仍然有效)。

从2000年起,Green threads在Sun JVM for Linux中被废弃(请参见Java[tm]Technology on the Linux Platform) 。 对于Solaris,自JDK 1.2以来即可使用本地线程(1998年)。 我甚至认为Windows从未有过Green thread的实现,但我找不到相关的参考资料。

正如维基百科的文章中所指出的那样,也有一些例外情况,我理解这主要是针对低功率(嵌入式)设备。


9
一个来自过去的古老事物。上个世纪的事了。你的教授需要跟上时代。 - user207421
1
@user1657170:你确切地对我写的哪一部分有异议? - Mat
2
@user1657170:我仍然不明白你在上面所写的是什么。阅读我从前Sun员工提供的链接文章,他们在Solaris 2.6左右放弃了绿色线程。 - Mat
4
纤维(以及在几乎所有平台上都出现的相关/类似的东西,或像 Erlang 进程一样一直存在)与Java中使用的“绿色线程”一词无关。当然,Sun / Oracle 有原生线程,并且JVM使用它们。如果您有具体的事实错误要指出,请引用准确的来源。 - Mat
3
在我上面发布的内容中,你如何称呼其中的三个链接,特别是那个与你在这个问题上没有参照的 Oracle 文档链接相矛盾的链接?顺便说一句,我已经不想回复你的评论了,这完全是浪费时间。 - Mat
显示剩余7条评论

27

绿色线程是在应用程序层面实现的线程,而不是在操作系统中实现。通常这样做是因为操作系统没有提供线程 API,或者它不符合您的需要。

因此,优点是您可以获得类似线程的功能。缺点是绿色线程无法真正使用多个核心。

早期的一些 JVM 使用了绿色线程(我记得 Blackdown JVM 对 Linux 的移植就是这样),但现在所有主流的 JVM 都使用真正的线程。可能还有一些嵌入式 JVM 仍在使用绿色线程。


21
有几种使用多个本地线程以利用多核或多处理器架构的绿色线程实现。这包括 .NET 中的线程库和 Java 的 Quasar 库。它们都使用与核心数一样多的本地线程,并使用绿色线程/纤程作为附加线程,在本地线程之间平衡它们。 - user1657170

27

绿色线程内存是从堆中分配的,而不是由操作系统创建堆栈。这可能会使并发线程增加一个数量级或更多。正如其他人已经提到的,这不会自动利用多处理器,但典型的用例通常用于阻塞I/O - 例如,绿色线程可能允许您处理10万个并发连接,而不是10,000个。

换句话说,对于特定规模的IO绑定操作,绿色线程更好。


3
使用绿色线程,你并没有真正拥有10万个并发连接。这只是一种假象 - Pacerier
11
从技术上讲,这些连接是并发的,但您不能同时处理它们的请求。 - Yike Lu
栈的位置并不能神奇地导致加速。 - user207421
绿色线程如何使10万个并发连接的结果出现在客户端屏幕上?这是相当神奇的吧?我们能否通过在屏幕上创建3D图形的幻象来复制它,而代码实际上并没有产生它? - user1657170

5
绿色线程是用户级线程,而不是内核级线程。它们由用户库而不是内核进行调度。您可以拥有自己的调度机制来调度线程,而不是依赖于操作系统调度器。
绿色线程模拟多线程环境,而不依赖于任何本地操作系统功能,并且它们在用户空间中管理,使它们能够在不具备本地线程支持的环境中工作。
性能方面: 在多核处理器上,本地线程实现可以自动分配工作到多个处理器,而绿色线程实现通常不能。 绿色线程在线程激活和同步方面显著优于Linux本地线程。
当绿色线程执行阻塞系统调用时,不仅该线程会被阻塞,而且进程中的所有线程都会被阻塞。

2
所有绿色线程在进程中如何被阻塞?如果该进程具有多个内核线程和执行器服务来分派绿色线程,会发生什么情况?如果执行系统调用的线程没有其他任务分派给它,会怎样呢?你的说法只在单线程环境下成立。 - marctrem
2
我的意思是,假设一个进程有n个绿色线程,对应1个内核线程,并且其中1个绿色线程进行了阻塞调用(由单个内核线程处理),那么所有与该内核线程相对应的绿色线程都将被阻塞。显然,对于一个进程中映射到n个绿色线程的m个内核线程,这种情况并不成立。无论哪种情况,你都不能说它是单线程环境——这取决于内核线程的调度。 - Aniket Thakur

5

当活跃线程大于处理器数量时,绿色线程比本地线程快得多。

Java最初支持绿色线程,但与大多数现代绿色线程实现不同,它无法在多个处理器之间进行扩展,使Java无法利用多个核心。

然后Java删除了绿色线程,仅依赖本地线程。这使Java线程比绿色线程慢。

请注意,我并没有特别谈论Java对绿色线程的实现,因为与其他绿色线程实现不同,它不能在多核或多处理器系统中进行扩展。


绿色线程在计算密集型任务方面并没有显著的速度优势,如果有的话,也不会更快。但对于某些特定任务来说,它是一个非常好的工具。 - JugsteR
是的,它们确实是。它们在执行计算方面并不比真正的线程更快,但它们在线程处理方面更快。它们不像真正的线程那样提供并行性。大多数线程的情况并不涉及计算机密集型任务。尽管你可能会认为人们过度使用线程,也许应该使用更多状态机,并将它们适应于过程式编程。 - user1657170
没有给出上下文,因此请不要做任何假设。由于您可以在任意数量的 CPU 上运行绿色线程,就像“普通”线程一样,在这种情况下,计算密集意味着不会发生任何切换。由于没有切换,使用绿色线程进行这种目的的好处被打败了。如果那不清楚,我很抱歉。因此,在我所谈论的特定场景中,绿色线程并没有给您带来任何实质性的性能优势。 - JugsteR

3
JAVA多线程有两种模型实现:
1.绿色线程模型 2.本地操作系统模型
绿色线程模型:由JVM管理的线程,不使用基础操作系统支持的线程称为绿色线程。很少的操作系统如Sun Solaris提供对绿色线程模型的支持。它已经过时,不建议使用。
本地操作系统模型:由JVM管理并借助底层操作系统支持的线程称为本地操作系统模型。所有Windows操作系统都支持本地操作系统模型。

2

绿色线程不由操作系统调度。

这意味着它们的调度发生在用户空间,而不是由内核处理。这意味着绿色线程通常不能使用所有CPU核心。

对于任何现代平台(例如x86或x64)运行Java,您将使用真正的线程。


4
没有理由让绿色线程不能利用多个CPU。例如,可以看看GHC和Go。 - user1804599

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