假设在两者中仅使用非阻塞操作,那么在简单的循环或顺序代码中使用green threads / lightweight threads
有什么好处吗?
for i := 0; i < 5; i++ {
go doSomethingExpensive() // using golang example
}
// versus
for i := 0; i < 5; i++ {
doSomethingExpensive()
}
据我所知
- 绿色线程有助于避免异步操作
上的一些回调地狱- 允许在 N 个内核线程上调度 M 个绿色线程
但
- 增加了一些复杂性和性能,需要调度程序
- 当语言支持它并且执行被拆分为不同的CPU时,更容易的跨线程通信(否则顺序代码更简单(
不,绿色线程根本没有性能优势。
如果线程正在执行非阻塞操作:
-
如果您只有一个物理内核,则多个线程没有任何好处(因为同一个内核必须执行所有内容,线程只会因为开销而使事情变慢(
-
与 CPU 内核一样多的线程具有性能优势,因为多个内核可以物理并行执行线程(请参阅 Play! 框架(
绿色线程 没有任何好处,因为它们由子调度程序从同一个真实线程运行,所以实际上绿色线程 == 1 个线程
如果线程正在执行阻塞操作,则情况可能有所不同:
- 多个线程是有意义的,因为一个线程可以被阻塞,但其他线程可以继续,所以阻塞只会减慢一个线程的速度
- 您可以通过将部分阻塞进程实现为一个线程来避免回调地狱。由于您可以在等待IO时自由地从一个线程阻止,因此您可以获得更简单的代码。
绿色线
绿色线程在设计上不是真正的线程,因此它们不会在多个 CPU 之间拆分,也不会并行工作。这可能会给出一个错误的理解,你可以避免同步 - 但是一旦你升级到真正的线程,缺乏适当的同步将引入一系列很好的问题。
绿色线程在早期的Java时代被广泛使用,当时JVM不支持真正的操作系统线程。绿色线程的一种变体,称为光纤,是Windows操作系统的一部分,例如MS SQL服务器大量使用它们来处理各种阻塞情况,而无需使用真实线程的沉重开销。
您不仅可以在绿色线程和真实线程之间进行选择,还可以考虑延续(https://www.playframework.com/documentation/1.3.x/asynchronous(
延续为您提供两全其美的优势:
- 你的代码在逻辑上看起来像是线性代码,没有回调地狱 实际上,代码
- 由真实线程执行,但是如果线程被阻塞,它将暂停其执行,并可以切换到执行其他代码。一旦阻塞条件发出信号,线程就可以切换回来并继续您的代码。
这种方法对资源非常友好。玩!框架使用的线程数与 CPU 内核数 (4-8( 一样多,但在性能方面击败了所有高端 Java 应用程序服务器。