green thread
{{distinguish|virtual thread}}
{{short description|Lightweight threading implemented in userspace}}
In computer programming, a green thread is a thread that is scheduled by a runtime library or virtual machine (VM) instead of natively by the underlying operating system (OS). Green threads emulate multithreaded environments without relying on any native OS abilities, and they are managed in user space instead of kernel space, enabling them to work in environments that do not have native thread support.{{cite web
|last1=Sintes
|first1=Tony
|date=2001-04-13
|df=mdy
|url=https://www.infoworld.com/article/2077383/four-for-the-ages.html
|title=Four for the ages
|website=JavaWorld
|accessdate=2020-07-14
|quote=Green threads, the threads provided by the JVM, run at the user level, meaning that the JVM creates and schedules the threads itself. Therefore, the operating system kernel doesn't create or schedule them. Instead, the underlying OS sees the JVM only as one thread. Green threads prove inefficient for a number of reasons. Foremost, green threads cannot take advantage of a multiprocessor system(...) Thus, the JVM threads are bound to run within that single JVM thread that runs inside a single processor.
|archive-date=2020-07-15
|archive-url=https://web.archive.org/web/20200715050100/https://www.infoworld.com/article/2077383/four-for-the-ages.html
|url-status=bot: unknown
}}
Etymology
Green threads refers to the name of the original thread library for Java programming language (that was released in version 1.1 and then Green threads were abandoned in version 1.3 to native threads). It was designed by The Green Team at Sun Microsystems.{{cite web |archive-url=https://web.archive.org/web/20080530073139/http://java.sun.com/features/1998/05/birthday.html |archive-date=2008-05-30 |url=http://java.sun.com/features/1998/05/birthday.html |website=java.sun.com |title=Java Technology: The Early Years |date=2014-12-22}}
History
Green threads were briefly available in Java between 1997 and 2000.
Green threads share a single operating system thread through co-operative concurrency and can therefore not achieve parallelism performance gains like operating system threads. The main benefit of coroutines and green threads is ease of implementation.
Performance
{{Update|section|date=February 2014}}
On a multi-core processor, native thread implementations can automatically assign work to multiple processors, whereas green thread implementations normally cannot.{{cite web
|url=http://www.jguru.com/faq/view.jsp?EID=143462
|title=What is the difference between "green" threads and "native" threads?
|website=jguru.com
|date=2000-09-06
|access-date=2009-06-01
|quote=On multi-CPU machines, native threads can run more than one thread simultaneously by assigning different threads to different CPUs. Green threads run on only one CPU.
}} Green threads can be started much faster on some VMs. On uniprocessor computers, however, the most efficient model has not yet been clearly determined.
Benchmarks on computers running the Linux kernel version 2.2 (released in 1999) have shown that:{{cite CiteSeerX |title=Comparative performance evaluation of Java threads for embedded applications: Linux Thread vs. Green Thread |citeseerx=10.1.1.8.9238}}
- Green threads significantly outperform Linux native threads on thread activation and synchronization.
- Linux native threads have slightly better performance on input/output (I/O) and context switching operations.
When a green thread executes a blocking system call, not only is that thread blocked, but all of the threads within the process are blocked.{{cite book |last=Stallings |first=William |title=Operating Systems, Internal and Design Principles |year=2008 |publisher=Prentice Hall |location=New Jersey |isbn=9780136006329 |pages=171}} To avoid that problem, green threads must use non-blocking I/O or asynchronous I/O operations, although the increased complexity on the user side can be reduced if the virtual machine implementing the green threads spawns specific I/O processes (hidden to the user) for each I/O operation.{{citation needed|date=November 2019}}
There are also mechanisms which allow use of native threads and reduce the overhead of thread activation and synchronization:
- Thread pools reduce the cost of spawning a new thread by reusing a limited number of threads.{{cite web
|url=https://blog.engineyard.com/2011/concurrency-in-jruby
|title=Concurrency in JRuby
|publisher=Engine Yard
|last=Sieger
|first=Nick
|date=2011-07-22
|access-date=2013-01-26
|quote=For systems with large volumes of email, this naive approach may not work well. Native threads carry a bigger initialization cost and memory overhead than green threads, so JRuby normally cannot support more than about 10,000 threads. To work around this, we can use a thread pool.
|archive-date=2014-01-30
|archive-url=https://web.archive.org/web/20140130094407/http://blog.engineyard.com/2011/concurrency-in-jruby
|url-status=dead
}}
- Languages which use virtual machines and native threads can use escape analysis to avoid synchronizing blocks of code when unneeded.{{cite web
|url=http://www-128.ibm.com/developerworks/java/library/j-jtp10185/
|title=Java theory and practice: Synchronization optimizations in Mustang
|publisher=IBM
|last=Goetz |first=Brian
|date=2005-10-18
|access-date=2013-01-26
}}
Green threads in the Java Virtual Machine
In Java 1.1, green threads were the only threading model used by the Java virtual machine (JVM),{{cite web
|url=http://docs.oracle.com/cd/E19455-01/806-3461/6jck06gqe/
|title=Java Threads in the Solaris Environment – Earlier Releases
|publisher=Oracle Corporation
|access-date=2013-01-26
|quote=As a result, several problems arose: Java applications could not interoperate with existing MT applications in the Solaris environment, Java threads could not run in parallel on multiprocessors, An MT Java application could not harness true OS concurrency for faster applications on either uniprocessors or multiprocessors. To substantially increase application performance, the green threads library was replaced with native Solaris threads for Java on the Solaris 2.6 platform; this is carried forward on the Solaris 7 and Solaris 8 platforms.
}} at least on Solaris. As green threads have some limitations compared to native threads, subsequent Java versions dropped them in favor of native threads.{{cite web
|url=http://www.sco.com/developers/java/j2sdk122-001/ReleaseNotes.html#THREADS
|title=Threads: Green or Native
|publisher=SCO Group
|access-date=2013-01-26
|quote=The performance benefit from using native threads on an MP machine can be dramatic. For example, using an artificial benchmark where Java threads are doing processing independent of each other, there can be a three-fold overall speed improvement on a 4-CPU MP machine.
|url=http://www.codestyle.org/java/faq-Threads.shtml#greenthread
|title=Threads: Green or Native
|publisher=codestyle.org
|access-date=2013-01-26
|archive-url=https://web.archive.org/web/20130116024929/http://www.codestyle.org/java/faq-Threads.shtml#greenthread
|archive-date=2013-01-16
|url-status=dead
|quote=There is a significant processing overhead for the JVM to keep track of thread states and swap between them, so green thread mode has been deprecated and removed from more recent Java implementations.
}}
An exception to this is the Squawk virtual machine, which is a mixture between an operating system for low-power devices and a Java virtual machine. It uses green threads to minimize the use of native code, and to support migrating its isolates.
Kilim{{cite web |url=https://github.com/kilim/kilim |title=kilim |website=GitHub |access-date=2016-06-09}}{{cite web |url=http://www.malhar.net/sriram/kilim/ |title=Kilim |website=www.malhar.net |access-date=2016-06-09}} and Quasar{{cite web |url=https://github.com/puniverse/quasar |title=Quasar Code on GitHub|website=GitHub}}{{cite web |url=https://paralleluniverse.co/quasar |title=Parallel Universe |access-date=6 December 2015 |archive-date=22 December 2015 |archive-url=https://web.archive.org/web/20151222173703/http://www.paralleluniverse.co/quasar/ |url-status=dead }}
are open-source projects which implement green threads on later versions of the JVM by modifying the Java bytecode produced by the Java compiler (Quasar also supports Kotlin and Clojure).
Green threads in other languages
There are some other programming languages that implement equivalents of green threads instead of native threads. Examples:
- Chicken Scheme uses lightweight user-level threads based on first-class continuations{{cite web |url=http://wiki.call-cc.org/man/4/Unit%20srfi-18/ |title=Chicken Scheme |publisher= |access-date=5 November 2017}}
- Common Lisp{{cite web |url=https://github.com/thezerobit/green-threads |title=thezerobit/green-threads|website=GitHub |access-date=2016-04-08}}
- CPython natively supports [https://docs.python.org/3/library/asyncio.html asyncio] since Version 3.4, alternative implementations exist like [http://greenlet.readthedocs.org greenlet], [http://eventlet.net/ eventlet] and [http://gevent.org gevent], PyPy{{cite web |url=http://doc.pypy.org/en/latest/stackless.html |title=Application-level Stackless features – PyPy 4.0.0 documentation|publisher= |access-date=6 December 2015}}
- Crystal offers fibers{{cite web |url=https://crystal-lang.org/docs/guides/concurrency.html |title=Concurrency: GitBook |website=crystal-lang.org |access-date=2018-04-03}}
- D offers fibers, used for asynchronous I/O{{Cite web |title=Fibers - Dlang Tour |url=https://tour.dlang.org/tour/en/multithreading/fibers |access-date=2022-05-02 |website=tour.dlang.org}}
- Dyalog APL terms them threads{{cite web |url=http://help.dyalog.com/latest/Content/Language/Introduction/Threads/Multithreading%20Overview.htm |title=Threads: Overview |website=Dyalog APL 17.0 Help |access-date=2018-12-14 |quote="A thread is a strand of execution in the APL workspace."}}
- Erlang{{cite tweet|number=1010485913393254401|user=joeerl|title=Erlang processes are emulated in the Erlang VM, like Green threads - we like them since this simplifies many proble… |date=23 June 2018}}
- Go implements so called [https://go.dev/tour/concurrency/1 goroutines]{{cite web |url=https://research.swtch.com/dogma |title=Go and Dogma |website=research!rsc |access-date=2017-01-14 |quote="for example both Go and Haskell need some kind of “green threads”, so there are more shared runtime challenges than you might expect."}}
- Haskell
- Julia uses green threads for its [https://docs.julialang.org/en/v1/base/parallel/ Tasks].
- Limbo{{Cite web|url=http://www.vitanuova.com/inferno/papers/limbo.html|title=The Limbo Programming Language|website=www.vitanuova.com|access-date=2019-04-01}}
- Lua uses [http://lua-users.org/wiki/CoroutinesTutorial coroutines] for concurrency. Lua 5.2 also offers true C coroutine semantics through the functions [http://www.lua.org/manual/5.2/manual.html#lua_yieldk lua_yieldk], [http://www.lua.org/manual/5.2/manual.html#lua_callk lua_callk], and [http://www.lua.org/manual/5.2/manual.html#lua_pcallk lua_pcallk]. The [http://coco.luajit.org/ CoCo] extension allows true C coroutine semantics for Lua 5.1.
- Nim provides asynchronous I/O and coroutines
- OCaml, since version 5.0, supports green threads through the [https://ocaml.org/p/domainslib/0.5.0/doc/Domainslib/Task/index.html Domainslib.Task] module
- occam, which prefers the term process instead of thread due to its origins in communicating sequential processes
- Perl supports green threads through [https://metacpan.org/pod/Coro coroutines]
- PHP supports green threads through [https://www.php.net/manual/en/language.fibers.php fibers] and [https://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html coroutines]
- Racket (native threads are also available through Places{{cite web |title=Racket Places|url=http://docs.racket-lang.org/reference/places.html |access-date=2011-10-13|quote=Places enable the development of parallel programs that take advantage of machines with multiple processors, cores, or hardware threads. A place is a parallel task that is effectively a separate instance of the Racket virtual machine.}})
- Ruby before version 1.9{{cite web |url=https://bugfactory.io/articles/multithreading-in-the-mri-ruby-interpreter/ |title=Multithreading in the MRI Ruby Interpreter {{!}} BugFactory |access-date=2024-06-18}}
- SML/NJ's implementation of Concurrent ML
- Smalltalk (most dialects: Squeak, VisualWorks, GNU Smalltalk, etc.)
- Stackless Python supports either preemptive multitasking or cooperative multitasking through microthreads (termed tasklets).{{cite web
|url=http://zope.stackless.com/about/sdocument_view
|title=Stackless.com: About Stackless
|quote=A round robin scheduler is built in. It can be used to schedule tasklets either cooperatively or preemptively.
|access-date=2008-08-27
|url-status=dead
|archive-url=https://web.archive.org/web/20120227125313/http://zope.stackless.com/about/sdocument_view
|archive-date=2012-02-27
}}
- Tcl has [http://www.tcl.tk/man/tcl8.6/TclCmd/coroutine.htm coroutines] and an event loop{{cite web |url=http://wiki.tcl.tk/1527 |title=Tcl event loop|publisher= |access-date=6 December 2015}}
The Erlang virtual machine has what might be called green processes – they are like operating system processes (they do not share state like threads do) but are implemented within the Erlang Run Time System (erts). These are sometimes termed green threads, but have significant differences{{clarify|date=June 2015}} from standard green threads.{{Citation needed|date=June 2015}}
In the case of GHC Haskell, a context switch occurs at the first allocation after a configurable timeout. GHC threads are also potentially run on one or more OS threads during their lifetime (there is a many-to-many relationship between GHC threads and OS threads), allowing for parallelism on symmetric multiprocessing machines, while not creating more costly OS threads than needed to run on the available number of cores.{{Citation needed|date=July 2010}}
Most Smalltalk virtual machines do not count evaluation steps; however, the VM can still preempt the executing thread on external signals (such as expiring timers, or I/O becoming available). Usually round-robin scheduling is used so that a high-priority process that wakes up regularly will effectively implement time-sharing preemption:
[
[(Delay forMilliseconds: 50) wait] repeat
] forkAt: Processor highIOPriority
Other implementations, e.g., QKS Smalltalk, are always time-sharing. Unlike most green thread implementations, QKS also supports preventing priority inversion.
Differences to virtual threads in the Java Virtual Machine
Virtual threads were introduced as a preview feature in Java 19{{cite web |url=https://openjdk.org/jeps/425 |title=JEP 425: Virtual Threads (Preview)|access-date=2024-01-25}} and stabilized in Java 21.{{cite web |url=https://openjdk.org/jeps/444 |title=JEP 444: Virtual Threads|access-date=2024-01-25}} Important differences between virtual threads and green threads are:
- Virtual threads coexist with existing (non-virtual) platform threads and thread pools.
- Virtual threads protect their abstraction:
- Unlike with green threads, sleeping on a virtual thread does not block the underlying carrier thread.
- Working with thread-local variables is deemphasized, and scoped values are suggested as a more lightweight replacement.{{cite web |url=https://openjdk.org/jeps/464 |title=JEP 464: Scoped Values (Second Preview)|access-date=2024-01-25}}
- Virtual threads can be cheaply suspended and resumed, making use of JVM support for the special
jdk.internal.vm.Continuation
class. - Virtual threads handle blocking calls by transparently unmounting from the carrier thread where possible, otherwise compensating by increasing the number of platform threads.
See also
References
{{Reflist}}
External links
- "[https://www.infoworld.com/article/2077383/four-for-the-ages.html Four for the ages]", JavaWorld article about Green threads
- [https://web.archive.org/web/20130116024929/http://www.codestyle.org/java/faq-Threads.shtml#greenthread Green threads on Java threads FAQ]
{{DEFAULTSORT:Green Threads}}