绿色线程与非绿色线程
Posted
技术标签:
【中文标题】绿色线程与非绿色线程【英文标题】:Green Threads vs Non Green Threads 【发布时间】:2011-08-08 11:03:52 【问题描述】:我想了解这些类型的线程提供的优势。
在哪些环境中,绿色线程比非绿色线程更好?有人说绿色线程更适合多核处理器。
任何预期的行为问题。
【问题讨论】:
绿色线程不太可能更适合多核处理器,因为它不会使用 mroe 而不是一个内核。如果绿色线程更好,那么您有一个不应该使用线程的程序(有时不应该使用线程) 哪里不应该使用线程? 【参考方案1】:***文章Green Threads很好地解释了这一点。
绿色线程是“用户级线程”。它们是由“普通”用户级进程而不是内核调度的。因此它们可用于在不提供该功能的平台上模拟多线程。
在 Java 环境中,绿色线程已成为过去。见文章JDK 1.1 for Solaris Developer's Guide。 (这是关于 Solaris,但不再使用绿色线程这一事实对通常的平台有效)。
自 1.3 版发布以来,Linux 的 Sun JVM 中放弃了绿色线程(请参阅 archive.org 上的 Java[tm] Technology on the Linux Platform)。那可以追溯到 2000 年。对于 Solaris,本地线程可从 JDK 1.2 开始使用。那可以追溯到 1998 年。我什至认为 Windows 没有绿色线程实现,但我找不到相关参考。
***文章中提到了一些例外情况,我收集的主要是低功耗(嵌入式)设备。
【讨论】:
过去的古代。上世纪。您的教授需要了解最新情况。 @user1657170:他们不是什么?你说的是什么“辅助线程”技术? @user1657170:仍然不明白我在上面写的内容中指的是什么。阅读我链接到的前 Sun 的文章,他们放弃了 Solaris 2.6 周围的绿色线程。 @user1657170:Fibers(以及这些天在几乎所有平台上出现的所有相关/类似的东西,或者像 Erlang 进程一样基本上永远存在)与绿色线程无关正如Java中使用的术语一样。当然 Sun/Oracle 有本地线程,当然 JVM 也使用它们。同样,如果您有具体要指出的内容实际上是错误的,请引用准确的来源。 您如何称呼我在上面发布的三个链接,尤其是与您在此问题上发布的内容相矛盾的 Oracle 文档链接?顺便说一句,我已经回答完了你的 cmets,这完全是浪费时间。【参考方案2】:绿色线程是在应用程序级别而不是在操作系统中实现的线程。这通常在操作系统不提供线程 API 或无法按您需要的方式工作时完成。
因此,优点是您完全可以获得类似线程的功能。缺点是绿色线程实际上不能使用多核。
有一些早期的 JVM 使用绿色线程(IIRC 将 Blackdown JVM 移植到 Linux),但现在所有主流 JVM 都使用真正的线程。可能有一些嵌入式 JVM 仍然使用绿色线程。
【讨论】:
绿色线程有几种实现方式,它们使用多个本机线程来利用多核或多处理器架构。这包括 .NET 中的线程库和 Java 的 Quasar 库。它们都使用与内核一样多的本机线程,并为其他线程使用绿色线程/光纤,在本机线程之间平衡它们。【参考方案3】:绿色线程内存是从堆中分配的,而不是操作系统为其创建的堆栈。这可能会使并发线程增加一个数量级或更多。正如其他人所提到的,这不会自动利用多个处理器,但是用例通常用于阻塞 I/O - 例如,绿色线程可能允许您处理 100k 并发连接,而不是 10k。
也就是说,绿色线程更适合一定规模的 IO 绑定操作。
【讨论】:
使用绿色线程,您实际上并没有 100k 的并发连接。这只是一个错觉。 从技术上讲,连接是并发的,你只是不能同时处理他们的请求。 堆栈的位置不会神奇地加快速度。 绿色线程如何让100k并发连接的结果出现在客户端屏幕上?这真是一种错觉?我们能否在代码不生成的情况下将 3D 图形复制为屏幕上的幻觉?【参考方案4】:绿色线程是用户级线程而不是内核级线程。它们由用户库而不是内核调度。您可以拥有自己的调度机制来调度线程,而不是依赖操作系统调度程序。
绿色线程在不依赖任何本机操作系统功能的情况下模拟多线程环境,并且它们在用户空间而不是内核空间中进行管理,使它们能够在不支持本机线程的环境中工作
表现:
在多核处理器上,本机线程实现可以自动将工作分配给多个处理器,而绿色线程实现通常不能。 绿色线程在线程激活和同步方面明显优于 Linux 原生线程。
当一个绿色线程执行一个阻塞系统调用时,不仅该线程被阻塞,而且进程内的所有线程都被阻塞。
【讨论】:
进程中的所有绿色线程如何被阻塞?如果这个进程有多个内核线程和一个执行器服务来在它们上调度绿色线程怎么办?如果执行系统调用的线程根本没有将其他任务分派给它怎么办?您的说法仅在单线程环境中成立。 我的意思是说一个进程的 n 个绿色线程有 1 个内核线程,并且 1 个绿色线程进行阻塞调用(由单个内核线程处理),然后所有与该内核对应的绿色线程线程将被阻塞。显然,这不适用于映射到进程的 n 个绿色线程的 m 个内核线程。无论哪种情况,您都不能说它是单线程环境 - 取决于内核线程调度。【参考方案5】:当活动线程比处理器多时,绿色线程比本机线程快得多。
Java 最初支持绿色线程,但与大多数现代绿色线程实现不同,它无法在多个处理器上扩展,这使得 Java 无法利用多个内核。
然后 Java 删除了绿色线程,以便仅依赖本机线程。这使得 Java 线程比绿色线程慢。
请注意,我并不是专门讨论绿色线程的 Java 实现,它确实有缺点,因为它与其他绿色线程不同,它无法在多核或多处理器系统中扩展。
【讨论】:
绿色线程对于计算密集型任务来说并没有明显更快,如果更快的话。不过,它是完成某些任务的绝佳工具。 是的。他们在计算方面并不快,但他们在线程方面更快。它们不像真正的胎面那样提供并行性。大多数线程情况不涉及计算机密集型任务。尽管您可能会争辩说人们过度使用线程,也许应该使用更多的状态机并将他们所做的事情融入过程编程中。 没有给出上下文,所以请不要假设任何事情。鉴于您可以在任意数量的 cpu 上运行绿色线程,就像“普通”线程一样,在这种情况下计算密集型意味着不会进行切换。由于没有切换,因此将绿色线程用于此类目的的好处被破坏了。如果不清楚,我很抱歉。所以不,我所说的特定场景中的绿色线程不会给您带来任何性能优势。【参考方案6】:JAVA 多线程由两种模型实现:
-
绿线模型
本机操作系统模型
绿色线程模型: 由 JVM 管理,不带底层操作系统支持的线程称为绿色线程。很少有像 Sun Solaris 这样的操作系统提供对绿色线程模型的支持。它已被弃用,不建议使用。
Native OS 模型: JVM 借助底层OS 管理的线程称为Native OS 模型。所有 windows 操作系统都支持原生操作系统模型。
【讨论】:
【参考方案7】:操作系统不调度绿色线程。
这意味着它们的调度发生在用户空间中,并且不由内核处理。这意味着通常不能使绿色线程使用所有 CPU 内核。
对于当今运行 Java 的任何主流平台(例如 x86 或 x64),您将使用真正的线程。
【讨论】:
绿色线程没有理由不能利用多个 CPU。例如,参见 GHC 和 Go。以上是关于绿色线程与非绿色线程的主要内容,如果未能解决你的问题,请参考以下文章