Benefits of green threads vs a simple loop

583 Views Asked by At

Is there any benefit to using green threads / lightweight threads over a simple loop or sequential code, assuming only non blocking operations are used in both?

for i := 0; i < 5; i++ {
    go doSomethingExpensive() // using golang example
}

// versus

for i := 0; i < 5; i++ {
    doSomethingExpensive()
}

As far as I can think of
- green threads help avoid a bit of callback hell on async operations
- allow scheduling of M green threads on N kernel threads

But
- add a bit of complexity and performance requiring a scheduler
- easier cross thread communication when the language supports it and the execution was split to different cpu's (otherwise sequential code is simpler)

1

There are 1 best solutions below

0
On

No, the green threads have no performance benefits at all.

If the threads are performing non-blocking operations:

  • Multiple threads have no benefits if you have only one physical core (since the same core has to execute everything, threads only makes things slower because of an overhead)

  • Up to as many threads as CPU cores you have have a performance benefit, since multiple cores can execute your threads physically parallel (see Play! framework)

  • Green threads have no benefits, since they are running from the same one real thread by a sub-scheduler, so actually green threads == 1 thread

If the threads are performing blocking operations, things may look different:

  • multiple threads makes sense, since one thread can be blocked, but the others can go on, so blocking slows down only one thread
  • you can avoid the callback-hell by just implementing your partially blocking process as one thread. Since you're free to block from one thread while e.g. waiting for IO, you get much simpler code.

Green threads

Green threads are not real threads by design, so they won't be split amongst multiple CPUs and are not indended to work in parallel. This can give a false understading that you can avoid synchronization - however once you upgrade to real threads the lack of proper synchronization will introduce a good set of issues.

Green threads were widely used in early Java days, when the JVM did not support real OS threads. A variant of green threads, called Fibers are part of the Windows operating system, and e.g. the MS SQL server uses them heavily to handle various blocking scenarios without the heavy overhead of using real threads.

You can choose not only amongst green threads and real threads, but may also consider continuations (https://www.playframework.com/documentation/1.3.x/asynchronous)

Continuations give you the best of both worlds:

  • your code logically looks like if it is a linear code, no callback hells
  • in reality the code is executed by real threads, however if a thread is getting blocked it suspends its execution and can switch to executing other code. Once the blocking condition signals, the thread can switch back and continue your code.

This approach is quite resource friendly. Play! framework uses as many threads as CPU cores you have (4-8) but beats all high-end Java application servers in terms of performance.