Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Coroutine
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{Short description|Computer software component}} {{external links|date=April 2024}} '''Coroutines''' are [[computer program]] components that allow execution to be suspended and resumed, generalizing [[subroutine]]s for [[non-preemptive multitasking|cooperative multitasking]]. Coroutines are well-suited for implementing familiar program components such as [[cooperative multitasking|cooperative task]]s, [[exception handling|exception]]s, [[event loop]]s, [[iterator]]s, [[lazy evaluation|infinite list]]s and [[pipeline (software)|pipe]]s. They have been described as "functions whose execution you can pause".<ref>{{Cite web |date=2016-02-11 |title=How the heck does async/await work in Python 3.5? |url=https://snarky.ca/how-the-heck-does-async-await-work-in-python-3-5/ |access-date=2023-01-10 |website=Tall, Snarky Canadian |language=en-ca |archive-date=2023-01-10 |archive-url=https://web.archive.org/web/20230110140918/https://snarky.ca/how-the-heck-does-async-await-work-in-python-3-5/ |url-status=live }}</ref> [[Melvin Conway]] coined the term ''coroutine'' in 1958 when he applied it to the construction of an [[assembly language|assembly program]].<ref name="KnuthVol1_1_4_5" /> The first published explanation of the coroutine appeared later, in 1963.<ref name="Conway1963"/> == Definition and types == There is no single precise definition of coroutine. In 1980 Christopher D. Marlin<ref>{{cite book |last1=Marlin |first1=Christopher |title=Coroutines: A Programming Methodology, a Language Design and an Implementation |date=1980 |publisher=Springer |isbn=3-540-10256-6}}</ref> summarized two widely-acknowledged fundamental characteristics of a coroutine: # the values of data local to a coroutine persist between successive calls; # the execution of a coroutine is suspended as control leaves it, only to carry on where it left off when control re-enters the coroutine at some later stage. Besides that, a coroutine implementation has 3 features: # the control-transfer mechanism. ''Asymmetric coroutines'' usually provide keywords like <code>yield</code> and <code>resume</code>. Programmers cannot freely choose which frame to yield to. The runtime only yields to the nearest caller of the current coroutine. On the other hand, in ''symmetric coroutines'', programmers must specify a yield destination. # whether coroutines are provided in the language as [[First-class citizen|first-class objects]], which can be freely manipulated by the programmer, or as constrained constructs; # whether a coroutine is able to suspend its execution from within nested function calls. Such a coroutine is a ''stackful coroutine''. One to the contrary is called ''stackless coroutines'', where unless marked as coroutine, a regular function can't use the keyword <code>yield</code>. The paper "Revisiting Coroutines"<ref>{{cite journal|citeseerx=10.1.1.58.4017|author1=Ana Lucia de Moura|author2=Roberto Ierusalimschy|title=Revisiting Coroutines|journal=ACM Transactions on Programming Languages and Systems|volume=31|issue=2|pages=1β31|year=2009|doi=10.1145/1462166.1462167|s2cid=9918449}}</ref> published in 2009 proposed term ''full coroutine'' to denote one that supports first-class coroutine and is stackful. Full Coroutines deserve their own name in that they have the same [[Expressive power (computer science)|expressive power]] as one-shot [[Continuation|continuations]] and delimited continuations. Full coroutines are either symmetric or asymmetric. Importantly, whether a coroutine is symmetric or asymmetric has no bearing on how expressive it can be as they are equally as expressive, though full coroutines are more expressive than non-full coroutines. While their expressive power is the same, asymmetrical coroutines more closely resemble routine based control structures in the sense that control is always passed back to the invoker, which programmers may find more familiar. ==Comparison with== ===Subroutines=== Subroutines are special cases of coroutines.<ref name="KnuthVol1_1_4_2"/> When subroutines are invoked, execution begins at the start, and once a subroutine exits, it is finished; an instance of a subroutine only returns once, and does not hold state between invocations. By contrast, coroutines can exit by calling other coroutines, which may later return to the point where they were invoked in the original coroutine; from the coroutine's point of view, it is not exiting but calling another coroutine.<ref name="KnuthVol1_1_4_2"/> Thus, a coroutine instance holds state, and varies between invocations; there can be multiple instances of a given coroutine at once. The difference between calling another coroutine by means of [[Yield (multithreading)|"yielding"]] to it and simply calling another routine (which then, also, would return to the original point), is that the relationship between two coroutines which yield to each other is not that of caller-callee, but instead symmetric. Any subroutine can be translated to a coroutine which does not call ''yield''.<ref name="Perlis1982_6"/> Here is a simple example of how coroutines can be useful. Suppose you have a consumer-producer relationship where one routine creates items and adds them to a queue and another removes items from the queue and uses them. For reasons of efficiency, you want to add and remove several items at once. The code might look like this: ''var'' q := new queue '''coroutine''' produce '''loop''' '''while''' q is not full create some new items add the items to q '''yield''' to consume '''coroutine''' consume '''loop''' '''while''' q is not empty remove some items from q use the items '''yield''' to produce '''call''' produce The queue is then completely filled or emptied before yielding control to the other coroutine using the ''yield'' command. The further coroutines calls are starting right after the ''yield'', in the outer coroutine loop. Although this example is often used as an introduction to [[thread (computing)|multithreading]], two threads are not needed for this: the ''yield'' statement can be implemented by a jump directly from one routine into the other. ===Threads=== Coroutines are very similar to [[Thread (computing)|threads]]. However, coroutines are [[cooperative multitasking|cooperatively multitasked]], whereas threads are typically [[Preemption (computing)|preemptively multitasked]]. Coroutines provide [[concurrency (computer science)|concurrency]], because they allow tasks to be performed out of order or in a changeable order, without changing the overall outcome, but they do not provide [[parallel computing|parallelism]], because they do not execute multiple tasks simultaneously. The advantages of coroutines over threads are that they may be used in a [[hard realtime|hard-realtime]] context ([[context switch|switching]] between coroutines need not involve any [[system calls]] or any [[blocking (computing)|blocking]] calls whatsoever), there is no need for synchronization primitives such as [[mutex]]es, semaphores, etc. in order to guard [[critical sections]], and there is no need for support from the operating system. It is possible to implement coroutines using preemptively-scheduled threads, in a way that will be transparent to the calling code, but some of the advantages (particularly the suitability for hard-realtime operation and relative cheapness of switching between them) will be lost. ===Generators=== {{Main|Generator (computer programming)}} Generators, also known as semicoroutines,<ref name="Ralston2000">{{cite book|author=Anthony Ralston|title=Encyclopedia of computer science|url=https://books.google.com/books?id=yQ9LAQAAIAAJ|access-date=11 May 2013|year=2000|publisher=Nature Pub. Group|isbn=978-1-56159-248-7}}</ref> are a subset of coroutines. Specifically, while both can yield multiple times, suspending their execution and allowing re-entry at multiple entry points, they differ in coroutines' ability to control where execution continues immediately after they yield, while generators cannot, instead transferring control back to the generator's caller.<ref>See for example ''[https://docs.python.org/reference/index.html The Python Language Reference] {{Webarchive|url=https://web.archive.org/web/20121024054933/https://docs.python.org/reference/index.html |date=2012-10-24 }}'' "https://docs.python.org/reference/expressions.html#yieldexpr {{Webarchive|url=https://web.archive.org/web/20121026064102/https://docs.python.org/reference/expressions.html#yieldexpr |date=2012-10-26 }} 5.2.10. Yield expressions]":<br /> "All of this makes generator functions quite similar to coroutines; they yield multiple times, they have more than one entry point and their execution can be suspended. The only difference is that a generator function cannot control where should the execution continue after it yields; the control is always transferred to the generator's caller."</ref> That is, since generators are primarily used to simplify the writing of [[iterator]]s, the <code>yield</code> statement in a generator does not specify a coroutine to jump to, but rather passes a value back to a parent routine. However, it is still possible to implement coroutines on top of a generator facility, with the aid of a top-level dispatcher routine (a [[trampoline (computing)|trampoline]], essentially) that passes control explicitly to child generators identified by tokens passed back from the generators: ''var'' q := new queue '''generator''' produce '''loop''' '''while''' q is not full create some new items add the items to q '''yield''' '''generator''' consume '''loop''' '''while''' q is not empty remove some items from q use the items '''yield''' '''subroutine''' dispatcher ''var'' d := new dictionary('''generator''' β '''iterator''') d[produce] := '''start''' consume d[consume] := '''start''' produce ''var'' current := produce '''loop''' '''call''' current current := '''next''' d[current] '''call''' dispatcher A number of implementations of coroutines for languages with generator support but no native coroutines (e.g. Python<ref name="MertzIBM"/> before 2.5) use this or a similar model. ===Mutual recursion=== {{Further|Mutual recursion}} Using coroutines for state machines or concurrency is similar to using [[mutual recursion]] with [[tail call]]s, as in both cases the control changes to a different one of a set of routines. However, coroutines are more flexible and generally more efficient. Since coroutines yield rather than return, and then resume execution rather than restarting from the beginning, they are able to hold state, both variables (as in a closure) and execution point, and yields are not limited to being in tail position; mutually recursive subroutines must either use shared variables or pass state as parameters. Further, each mutually recursive call of a subroutine requires a new stack frame (unless [[tail call elimination]] is implemented), while passing control between coroutines uses the existing contexts and can be implemented simply by a jump. ==Common uses== Coroutines are useful to implement the following: * [[State machine]]s within a single subroutine, where the state is determined by the current entry/exit point of the procedure; this can result in more readable code compared to use of [[goto]], and may also be implemented via [[mutual recursion]] with [[tail call]]s. * [[Actor model]] of concurrency, for instance in [[video game]]s. Each actor has its own procedures (this again logically separates the code), but they voluntarily give up control to central scheduler, which executes them sequentially (this is a form of [[cooperative multitasking]]). * [[Generator (computer programming)|Generator]]s, and these are useful for [[Stream (computing)|streams]]{{snd}}particularly input/output{{snd}}and for generic traversal of data structures. * [[Communicating sequential processes]] where each sub-process is a coroutine. Channel inputs/outputs and blocking operations yield coroutines and a scheduler unblocks them on completion events. Alternatively, each sub-process may be the parent of the one following it in the data pipeline (or preceding it, in which case the pattern can be expressed as nested generators). * Reverse communication, commonly used in mathematical software, wherein a procedure such as a solver, integral evaluator, ... needs the using process to make a computation, such as evaluating an equation or integrand. ==Native support== Coroutines originated as an [[assembly language]] method, but are supported in some [[high-level programming language]]s. {{Div col|colwidth=18em}} * [[Aikido (programming language)|Aikido]] * [[AngelScript]] * [[Ballerina (programming language)|Ballerina]] * [[BCPL]] * [[Pascal (programming language)|Pascal]] (Borland [[Turbo Pascal]] 7.0 with uThreads module) * [[BETA (programming language)|BETA]] * [[BLISS]] * [[C++]] (Since C++20) * [[C Sharp (programming language)|C#]] (Since 2.0) * [[Chapel (programming language)|Chapel]] * [[ChucK]] * [[CLU (programming language)|CLU]] * [[D (programming language)|D]] * [[Dynamic C]] * [[Erlang (programming language)|Erlang]] * [[F Sharp (programming language)|F#]] * [[Factor (programming language)|Factor]] * [[GameMonkey Script]] * [[Godot (game engine)|GDScript]] (Godot's scripting language) * [[Haskell (programming language)|Haskell]]<ref>{{cite web | title = Coroutine: Type-safe coroutines using lightweight session types | url = http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Coroutine | access-date = 2008-12-18 | archive-date = 2013-01-20 | archive-url = https://web.archive.org/web/20130120062237/http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Coroutine | url-status = live }}</ref><ref>{{cite web | title = Co-routines in Haskell | url = https://axman6.com/posts/2016-07-10-Linear-resources-in-haskell.html | access-date = 2019-01-13 | archive-date = 2020-01-09 | archive-url = https://web.archive.org/web/20200109052929/https://axman6.com/posts/2016-07-10-Linear-resources-in-haskell.html | url-status = live }}</ref> * [[High Level Assembly]]<ref>{{cite web | title = The Coroutines Module (coroutines.hhf) | url = http://www.plantation-productions.com/Webster/HighLevelAsm/HLADoc/HLAStdlib/1_HTML/HLAStdlib.htm#50618574_pgfId-998318 | work = HLA Standard Library Manual | access-date = 2013-12-04 | archive-date = 2019-04-27 | archive-url = https://web.archive.org/web/20190427211627/http://plantation-productions.com/Webster/HighLevelAsm/HLADoc/HLAStdlib/1_HTML/HLAStdlib.htm#50618574_pgfId-998318 | url-status = live }}</ref> * [[Icon (programming language)|Icon]] * [[Io (programming language)|Io]] * [[JavaScript]] (since 1.7, standardized in ECMAScript 6)<ref>{{cite web | title = New in JavaScript 1.7 | url = https://developer.mozilla.org/en/docs/New_in_JavaScript_1.7 | access-date = 2018-06-18 | archive-date = 2009-03-08 | archive-url = https://web.archive.org/web/20090308111529/https://developer.mozilla.org/en//docs//New_in_JavaScript_1.7 }}</ref><!-- Does JavaScript belong here? See the link. --> ECMAScript 2017 also includes [[await]] support. * [[Julia (programming language)|Julia]]<ref>{{cite web| title=Julia Manual - Control Flow - Tasks (aka Coroutines)| url=https://docs.julialang.org/en/v1/manual/asynchronous-programming/#man-asynchronous| access-date=2021-02-10| archive-date=2021-01-23| archive-url=https://web.archive.org/web/20210123235831/https://docs.julialang.org/en/v1/manual/asynchronous-programming/#man-asynchronous| url-status=live}}</ref> * [[Kotlin (programming language)|Kotlin]] (since 1.1)<ref>{{cite web| title=What's New in Kotlin 1.1| url=https://kotlinlang.org/docs/reference/whatsnew11.html#coroutines-experimental| access-date=2017-02-27| archive-date=2019-08-11| archive-url=https://web.archive.org/web/20190811233854/https://kotlinlang.org/docs/reference/whatsnew11.html#coroutines-experimental| url-status=live}}</ref> * [[Limbo (programming language)|Limbo]] * [[Lua (programming language)|Lua]]<ref>{{Cite web|url=http://www.lua.org/manual/5.2/manual.html#2.6|title=Lua 5.2 Reference Manual|website=www.lua.org|access-date=2012-06-19|archive-date=2018-01-13|archive-url=https://web.archive.org/web/20180113023237/http://www.lua.org/manual/5.2/manual.html#2.6|url-status=live}}</ref> * [[Lucid (programming language)|Lucid]] * [[ΞΌC++]] * [[Modula-2]] * [[Nemerle]] * [[Perl 5]] (using the [https://metacpan.org/pod/Coro Coro module]) * [[PHP]] (with [https://github.com/facebook/hiphop-php HipHop], native since PHP 5.5) * [[Picolisp]] * [[Prolog]] * [[Python (programming language)|Python]] (since 2.5,<ref>{{Cite web|url=https://stackabuse.com/python-async-await-tutorial/|title=Python async/await Tutorial|date=December 17, 2015|website=Stack Abuse|access-date=October 21, 2019|archive-date=November 29, 2019|archive-url=https://web.archive.org/web/20191129130627/https://stackabuse.com/python-async-await-tutorial/|url-status=live}}</ref> with improved support since 3.3 and with explicit syntax since 3.5<ref>{{Cite web|url=https://docs.python.org/3/reference/compound_stmts.html#async-def|title=8. Compound statements β Python 3.8.0 documentation|website=docs.python.org|access-date=2016-03-11|archive-date=2019-11-27|archive-url=https://web.archive.org/web/20191127123528/https://docs.python.org/3/reference/compound_stmts.html#async-def|url-status=live}}</ref>) * [[Racket (programming language)]] * [[Raku (programming language)|Raku]]<ref>{{cite web|title=Gather and/or Coroutines|url=https://perl6advent.wordpress.com/2012/12/19/gather-andor-coroutines/|date=2012-12-19|access-date=2015-06-08|archive-date=2020-06-13|archive-url=https://web.archive.org/web/20200613175447/https://perl6advent.wordpress.com/2012/12/19/gather-andor-coroutines/|url-status=live}}</ref> * [[Ruby (programming language)|Ruby]] * [[Sather]] * [[Scheme (programming language)|Scheme]] * [[Self (programming language)|Self]] * [[Simula]] 67<ref name="Dahl1972">{{cite book|title=Structured Programming|editor1-first=O.J.|editor1-last=Dahl|editor2-first=C.A.R.|editor2-last=Hoare|publisher=Academic Press|year=1972|isbn=978-0-12-200550-3|location=London, UK|pages=175β220|chapter=Hierarchical Program Structures}}</ref> * [[Smalltalk]] * [[Squirrel (programming language)|Squirrel]] * [[Stackless Python]] * [[SuperCollider]]<ref>McCartney, J. [http://portal.acm.org/citation.cfm?id=1245228 "Rethinking the Computer Music Programming Language: SuperCollider"]. Computer Music Journal, 26(4):61-68. MIT Press, 2002.</ref> * [[Tcl]] (since 8.6) * [[urbiscript]] <!-- Coroutines can be implemented in any language, so please limit this list to languages with native support. Specifically, don't re-add the following entries without consideration: * [[C Sharp (programming language)|C#]] * [[Perl]] * [[Smalltalk]] --> {{div col end}} Since [[continuation]]s can be used to implement coroutines, programming languages that support them can also quite easily support coroutines. ==Implementations== {{As of|2003}}, many of the most popular programming languages, including C and its derivatives, do not have built-in support for coroutines within the language or their standard libraries. This is, in large part, due to the limitations of [[call stack|stack-based]] subroutine implementation. An exception is the C++ library [http://www.boost.org/doc/libs/1_55_0/libs/context/doc/html/index.html Boost.Context], part of [http://www.boost.org boost libraries], which supports context swapping on ARM, MIPS, PowerPC, SPARC and x86 on POSIX, Mac OS X and Windows. Coroutines can be built upon Boost.Context. In situations where a coroutine would be the natural implementation of a mechanism, but is not available, the typical response is to use a [[Closure (computer science)|closure]]{{snd}}a subroutine with state variables ([[static variable]]s, often boolean flags) to maintain an internal state between calls, and to transfer control to the correct point. Conditionals within the code result in the execution of different code paths on successive calls, based on the values of the state variables. Another typical response is to implement an explicit state machine in the form of a large and complex [[switch statement]] or via a [[goto]] statement, particularly a [[computed goto]]. Such implementations are considered difficult to understand and maintain, and a motivation for coroutine support. [[thread (computing)|Threads]], and to a lesser extent [[fiber (computer science)|fibers]], are an alternative to coroutines in mainstream programming environments today. Threads provide facilities for managing the real-time cooperative interaction of ''simultaneously'' executing pieces of code. Threads are widely available in environments that support C (and are supported natively in many other modern languages), are familiar to many programmers, and are usually well-implemented, well-documented and well-supported. However, as they solve a large and difficult problem they include many powerful and complex facilities and have a correspondingly difficult learning curve. As such, when a coroutine is all that is needed, using a thread can be overkill. One important difference between threads and coroutines is that threads are typically preemptively scheduled while coroutines are not. Because threads can be rescheduled at any instant and can execute concurrently, programs using threads must be careful about [[lock (computer science)|locking]]. In contrast, because coroutines can only be rescheduled at specific points in the program and do not execute concurrently, programs using coroutines can often avoid locking entirely. This property is also cited as a benefit of [[event-driven programming|event-driven]] or asynchronous programming. Since fibers are cooperatively scheduled, they provide an ideal base for implementing coroutines above.<ref name="msdn-wrap">[http://msdn.microsoft.com/msdnmag/issues/03/09/CoroutinesinNET/default.aspx Implementing Coroutines for .NET by Wrapping the Unmanaged Fiber API] {{Webarchive|url=https://web.archive.org/web/20080907164722/http://msdn.microsoft.com/msdnmag/issues/03/09/CoroutinesinNET/default.aspx |date=2008-09-07 }}, Ajai Shankar, [[MSDN Magazine]]</ref> However, system support for fibers is often lacking compared to that for threads. ===C=== In order to implement general-purpose coroutines, a second [[call stack]] must be obtained, which is a feature not directly supported by the [[C (programming language)|C]] language. A reliable (albeit platform-specific) way to achieve this is to use a small amount of [[inline assembly]] to explicitly manipulate the stack pointer during initial creation of the coroutine. This is the approach recommended by [[Tom Duff]] in a discussion on its relative merits vs. the method used by [[Protothreads]].<ref name="duff">{{Cite web| url=https://brainwagon.org/2005/03/05/coroutines-in-c/#comment-1878| title=Coroutines in C β brainwagon| date=5 March 2005| access-date=7 August 2018| archive-date=23 July 2019| archive-url=https://web.archive.org/web/20190723071827/https://brainwagon.org/2005/03/05/coroutines-in-c/#comment-1878| url-status=live}}</ref>{{Primary source inline|date=March 2022}} On platforms which provide the [[POSIX]] [[sigaltstack]] system call, a second call stack can be obtained by calling a springboard function from within a signal handler<ref name="rse-pmt">{{cite conference|url=https://www.gnu.org/software/pth/rse-pmt.ps|title=Portable Multithreading β The Signal Stack Trick For User-Space Thread Creation|format=PS|conference=USENIX Annual Technical Conference|date=18β23 June 2000|location=San Diego, USA|author=Ralf S. Engelschall|access-date=27 November 2017|archive-date=31 October 2019|archive-url=https://web.archive.org/web/20191031120105/http://www.gnu.org/software/pth/rse-pmt.ps|url-status=live}}</ref><ref name="libco">{{Cite web|url=https://code.byuu.org/libco|title=libco|website=code.byuu.org}}{{Dead link|date=March 2022 |bot=InternetArchiveBot |fix-attempted=yes }}</ref> to achieve the same goal in portable C, at the cost of some extra complexity. C libraries complying to [[POSIX]] or the [[Single Unix Specification]] (SUSv3) provided such routines as [[setcontext|getcontext, setcontext, makecontext and swapcontext]], but these functions were declared obsolete in POSIX 1.2008.<ref>{{Cite web|url=http://man7.org/linux/man-pages/man3/getcontext.3.html|title=getcontext(3) - Linux manual page|website=man7.org|access-date=2017-11-22|archive-date=2019-11-27|archive-url=https://web.archive.org/web/20191127031557/http://man7.org/linux/man-pages/man3/getcontext.3.html|url-status=live}}</ref> Once a second call stack has been obtained with one of the methods listed above, the [[setjmp/longjmp|setjmp and longjmp]] functions in the [[standard C library]] can then be used to implement the switches between coroutines. These functions save and restore, respectively, the [[stack pointer]], [[program counter]], callee-saved [[processor register|registers]], and any other internal state as required by the [[application binary interface|ABI]], such that returning to a coroutine after having yielded restores all the state that would be restored upon returning from a function call. Minimalist implementations, which do not piggyback off the setjmp and longjmp functions, may achieve the same result via a small block of [[inline assembly]] which swaps merely the stack pointer and program counter, and [[Clobbering#Assembly|clobbers]] all other registers. This can be significantly faster, as setjmp and longjmp must conservatively store all registers which may be in use according to the ABI, whereas the clobber method allows the compiler to store (by spilling to the stack) only what it knows is actually in use. Due to the lack of direct language support, many authors have written their own libraries for coroutines which hide the above details. Russ Cox's libtask library<ref name="libtask">http://swtch.com/libtask/ {{Webarchive|url=https://web.archive.org/web/20191115104620/http://swtch.com/libtask/ |date=2019-11-15 }} - Russ Cox's libtask coroutine library for FreeBSD, Linux, Mac OS X, and SunOS</ref> is a good example of this genre. It uses the context functions if they are provided by the native C library; otherwise it provides its own implementations for ARM, PowerPC, Sparc, and x86. Other notable implementations include libpcl,<ref>[http://xmailserver.org/libpcl.html ''Portable Coroutine Library''] {{Webarchive|url=https://web.archive.org/web/20051214201518/http://xmailserver.org/libpcl.html |date=2005-12-14 }} - C library using POSIX/SUSv3 facilities</ref> coro,<ref>http://www.goron.de/~froese/coro/ {{Webarchive|url=https://web.archive.org/web/20060110123338/http://www.goron.de/~froese/coro/ |date=2006-01-10 }} - Edgar Toernig's coro library for x86, Linux & FreeBSD</ref> lthread,<ref>https://github.com/halayli/lthread {{Webarchive|url=https://web.archive.org/web/20200613175536/https://github.com/halayli/lthread |date=2020-06-13 }} - lthread is a multicore/multithread coroutine library written in C</ref> libCoroutine,<ref>{{cite web|url=http://dekorte.com/projects/opensource/libcoroutine/|title=libcoroutine: A portable coroutine implementation|access-date=2013-09-06|archive-date=2019-11-12|archive-url=https://web.archive.org/web/20191112231845/http://dekorte.com/projects/opensource/libcoroutine/}} for FreeBSD, Linux, OS X PPC and x86, SunOS, Symbian and others</ref> libconcurrency,<ref>{{cite web|url=http://code.google.com/p/libconcurrency/libconcurrency|title=libconcurrency - A scalable concurrency library for C}} a simple C library for portable stack-switching coroutines</ref> libcoro,<ref>{{cite web|url=http://software.schmorp.de/pkg/libcoro.html|title=libcoro: C-library that implements coroutines (cooperative multitasking) in a portable fashion|access-date=2008-04-17|archive-date=2019-12-02|archive-url=https://web.archive.org/web/20191202064402/http://software.schmorp.de/pkg/libcoro.html|url-status=live}} used as the basis for the Coro perl module.</ref> ribs2,<ref>{{Cite web|url=https://github.com/aolarchive/ribs2|title=RIBS (Robust Infrastructure for Backend Systems) version 2: aolarchive/ribs2|date=August 13, 2019|via=GitHub|access-date=October 21, 2019|archive-date=April 22, 2020|archive-url=https://web.archive.org/web/20200422015941/https://github.com/aolarchive/ribs2|url-status=live}}</ref> libdill.,<ref>{{Cite web|url=http://libdill.org/|title=libdill|website=libdill.org|access-date=2019-10-21|archive-date=2019-12-02|archive-url=https://web.archive.org/web/20191202174632/http://libdill.org/}}</ref> libaco,<ref>{{Cite web|url=https://github.com/hnes/libaco|title=A blazing fast and lightweight C asymmetric coroutine library π β πβ π: hnes/libaco|date=October 21, 2019|via=GitHub|access-date=October 16, 2018|archive-date=November 29, 2018|archive-url=https://web.archive.org/web/20181129154044/https://github.com/hnes/libaco|url-status=live}}</ref> and libco.<ref name="libco" /> In addition to the general approach above, several attempts have been made to approximate coroutines in C with combinations of subroutines and macros. [[Simon Tatham]]'s contribution,<ref name="tatham">{{cite web|url=http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html|author=Simon Tatham|title=Coroutines in C|year=2000|access-date=2003-09-19|archive-date=2019-11-09|archive-url=https://web.archive.org/web/20191109155253/https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html|url-status=live}}</ref> based on [[Duff's device]], is a notable example of the genre, and is the basis for [[Protothread]]s and similar implementations.<ref>{{Cite web|url=https://github.com/jsseldenthuis/coroutine|title=Stackless coroutine implementation in C and C++: jsseldenthuis/coroutine|date=March 18, 2019|via=GitHub|access-date=March 18, 2019|archive-date=June 13, 2020|archive-url=https://web.archive.org/web/20200613175624/https://github.com/jsseldenthuis/coroutine|url-status=live}}</ref> In addition to Duff's objections,<ref name="duff" /> Tatham's own comments provide a frank evaluation of the limitations of this approach: "As far as I know, this is the worst piece of C hackery ever seen in serious production code."<ref name="tatham" /> The main shortcomings of this approximation are that, in not maintaining a separate stack frame for each coroutine, local variables are not preserved across yields from the function, it is not possible to have multiple entries to the function, and control can only be yielded from the top-level routine.<ref name="duff" /> ===C++=== * [[C++20]] introduced standardized coroutines as stackless functions that can be suspended in the middle of execution and resumed at a later point. The suspended state of a coroutine is stored on the heap.<ref>http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4680.pdf {{Webarchive|url=https://web.archive.org/web/20240630124010/https://open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4680.pdf |date=2024-06-30 }} - Technical specification for coroutines</ref> Implementation of this standard is ongoing, with the G++ and MSVC compilers currently fully supporting standard coroutines in recent versions.<ref>https://en.cppreference.com/w/cpp/compiler_support#cpp20 {{Webarchive|url=https://web.archive.org/web/20220808151657/https://en.cppreference.com/w/cpp/compiler_support#cpp20 |date=2022-08-08 }} - Current compiler support for standard coroutines</ref> * [https://github.com/David-Haim/concurrencpp concurrencpp] - a C++20 library which provides third-party support for C++20 coroutines, in the form of awaitable-tasks and executors that run them. *[http://www.boost.org/doc/libs/1_57_0/libs/coroutine/doc/html/index.html Boost.Coroutine] - created by Oliver Kowalke, is the official released portable coroutine library of [http://boost.org boost] since version 1.53. The library relies on [http://www.boost.org/doc/libs/1_53_0/libs/context/doc/html/index.html Boost.Context] and supports ARM, MIPS, PowerPC, SPARC and X86 on POSIX, Mac OS X and Windows. *[http://www.boost.org/doc/libs/1_61_0/libs/coroutine2/doc/html/index.html Boost.Coroutine2] - also created by Oliver Kowalke, is a modernized portable coroutine library since boost version 1.59. It takes advantage of C++11 features, but removes the support for symmetric coroutines. *[https://github.com/mozy/mordor Mordor] - In 2010, [[Mozy]] open sourced a C++ library implementing coroutines, with an emphasis on using them to abstract [[asynchronous I/O]] into a more familiar sequential model.<ref>http://mozy.com/blog/announcements/open-source-and-mozy-the-debut-of-mozy-code/ {{Webarchive|url=https://web.archive.org/web/20101027063523/http://mozy.com/blog/announcements/open-source-and-mozy-the-debut-of-mozy-code/ |date=2010-10-27 }} - Open Source and Mozy: The Debut of Mozy Code</ref> *[https://github.com/jamboree/co2 CO2] - stackless coroutine based on C++ [[preprocessor]] tricks, providing await/yield emulation. *[https://github.com/scummvm/scummvm/blob/master/common/coroutines.h ScummVM] - The [[ScummVM]] project implements a light-weight version of stackless coroutines based on [http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html Simon Tatham's article]. *[https://github.com/tonbit/coroutine tonbit::coroutine] - C++11 single .h asymmetric coroutine implementation via ucontext / fiber * Coroutines landed in [[Clang]] in May 2017, with libc++ implementation ongoing.<ref>https://twitter.com/eric01/status/867473461836263424 - EricWF: Coroutines are now in Clang Trunk! Working on the Libc++ implementation now.</ref> * [https://github.com/infinit/elle elle] by Docker * [https://oatpp.io/docs/oatpp-coroutines/ oatpp-coroutines] - stackless coroutines with scheduling designed for high-concurrency level I/O operations. Used in the [https://oatpp.io/benchmark/websocket/5-million/ 5-million WebSocket connections] experiment by Oat++. Part of the [https://github.com/oatpp/oatpp Oat++] web framework. ===C#=== [[C Sharp 2.0|C# 2.0]] added semi-coroutine ([[generator (computer programming)|generator]]) functionality through the iterator pattern and <code>yield</code> keyword.<ref>{{cite web |last1=Wagner |first1=Bill |title=Iterators |url=https://learn.microsoft.com/en-us/dotnet/csharp/iterators |website=C# documentation |publisher=[[Microsoft]] |date=11 November 2021 |via=Microsoft Learn |access-date=16 February 2023 |archive-date=11 April 2024 |archive-url=https://web.archive.org/web/20240411225954/https://learn.microsoft.com/en-us/dotnet/csharp/iterators |url-status=live }}</ref><ref>{{cite web |last1=Wagner |first1=Bill |title=The history of C# |url=https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history#c-version-20 |website=C# documentation |publisher=[[Microsoft]] |date=13 February 2023 |via=Microsoft Learn |at=C# version 2.0 |access-date=16 February 2023 |archive-date=28 April 2023 |archive-url=https://web.archive.org/web/20230428185411/https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history#c-version-20 |url-status=live }}</ref> [[C Sharp 5.0|C# 5.0]] includes [[await]] syntax support. In addition: *The '''[https://github.com/MindTouch/dream MindTouch Dream]''' REST framework provides an implementation of coroutines based on the C# 2.0 iterator pattern. * The '''[http://caliburn.codeplex.com/Wiki/View.aspx?title=IResult Caliburn]''' ({{Webarchive|url=https://archive.today/20130119150506/http://caliburn.codeplex.com/Wiki/View.aspx?title=IResult |date=2013-01-19 }}) screen patterns framework for WPF uses C# 2.0 iterators to ease UI programming, particularly in asynchronous scenarios. *The '''[http://www.wintellect.com/PowerThreading.aspx Power Threading Library]''' ({{Webarchive|url=https://web.archive.org/web/20100324183723/http://wintellect.com/PowerThreading.aspx |date=2010-03-24 }}) by [[Jeffrey Richter]] implements an AsyncEnumerator that provides simplified Asynchronous Programming Model using iterator-based coroutines. *The [[Unity (game engine)|Unity]] game engine implements coroutines. *The '''[https://github.com/yevhen/Servelat-Pieces Servelat Pieces]''' project by [[Yevhen Bobrov]] provides transparent asynchrony for Silverlight WCF services and ability to asynchronously call any synchronous method. The implementation is based on Caliburn's Coroutines iterator and C# iterator blocks. *'''[https://github.com/michaelmeling/StreamThreads StreamThreads]''' is an open-source, light-weight C# co-routine library based on iterator extension methods. It supports error handling and return values. ===Clojure=== [https://github.com/leonoel/cloroutine Cloroutine] is a third-party library providing support for stackless coroutines in [[Clojure]]. It's implemented as a macro, statically splitting an arbitrary code block on arbitrary var calls and emitting the coroutine as a stateful function. ===D=== [[D (programming language)|D]] implements coroutines as its standard library class [https://tour.dlang.org/tour/en/multithreading/fibers Fiber] A ''generator'' makes it trivial to expose a fiber function as an ''input range'', making any fiber compatible with existing range algorithms. ===Go=== [[Go (programming language)|Go]] has a built-in concept of "[[goroutine]]s", which are lightweight, independent processes managed by the Go runtime. A new goroutine can be started using the "go" keyword. Each goroutine has a variable-size stack which can be expanded as needed. Goroutines generally communicate using Go's built-in channels.<ref>{{Cite web |title=Goroutines - Effective Go |url=https://go.dev/doc/effective_go#goroutines |access-date=2022-11-28 |website=go.dev |language=en |archive-date=2024-06-27 |archive-url=https://web.archive.org/web/20240627152229/https://go.dev/doc/effective_go#goroutines |url-status=live }}</ref><ref>{{Cite web |title=Go statements - The Go Specification |url=https://go.dev/ref/spec#Go_statements |access-date=2022-11-28 |website=go.dev |language=en |archive-date=2022-11-27 |archive-url=https://web.archive.org/web/20221127233150/https://go.dev/ref/spec#Go_statements |url-status=live }}</ref><ref>{{Cite web |title=Goroutines - A Tour of Go |url=https://go.dev/tour/concurrency/1 |access-date=2022-11-28 |website=go.dev |archive-date=2024-06-26 |archive-url=https://web.archive.org/web/20240626173728/https://go.dev/tour/concurrency/1 |url-status=live }}</ref><ref>{{Cite web|url=https://go.dev/doc/faq|title=Frequently Asked Questions (FAQ) - The Go Programming Language|website=go.dev|access-date=2022-11-28|archive-date=2021-11-22|archive-url=https://web.archive.org/web/20211122200010/https://go.dev/doc/faq|url-status=live}}</ref> However, goroutines are not coroutines (for instance, local data does not persist between successive calls).<ref>{{Cite web |title=Coroutines for Go |url=https://research.swtch.com/coro |access-date=2024-10-24 |website=swtch.com |language=en |archive-date=2024-09-28 |archive-url=https://web.archive.org/web/20240928032458/https://research.swtch.com/coro |url-status=live }}</ref> ===Java=== There are several implementations for coroutines in [[Java (programming language)|Java]]. Despite the constraints imposed by Java's abstractions, the JVM does not preclude the possibility.<ref name="jvmsummit">{{cite web|url=http://www.wiki.jvmlangsummit.com/images/2/2b/JVMLanguageSummit_Stadler_Continuations.pdf|author=Lukas Stadler|series=JVM Language Summit|title=JVM Continuations|year=2009|access-date=2011-10-03|archive-date=2012-04-23|archive-url=https://web.archive.org/web/20120423215434/http://wiki.jvmlangsummit.com/images/2/2b/JVMLanguageSummit_Stadler_Continuations.pdf|url-status=live}}</ref> There are four general methods used, but two break bytecode portability among standards-compliant JVMs. * Modified JVMs. It is possible to build a patched JVM to support coroutines more natively. The [http://openjdk.java.net/projects/mlvm/ Da Vinci JVM] has had patches created.<ref name="javanet-forax">{{cite web|url=http://weblogs.java.net/blog/forax/archive/2009/11/19/holy-crap-jvm-has-coroutinecontinuationfiber-etc|author=Remi Forax|archive-url=https://web.archive.org/web/20150319052055/http://weblogs.java.net/blog/forax/archive/2009/11/19/holy-crap-jvm-has-coroutinecontinuationfiber-etc|archive-date=19 March 2015|title=Holy crap: JVM has coroutine/continuation/fiber etc.|date=19 November 2009}}</ref> * Modified bytecode. Coroutine functionality is possible by rewriting regular Java bytecode, either on the fly or at compile time. Toolkits include [http://commons.apache.org/sandbox/commons-javaflow/ Javaflow], [http://code.google.com/p/coroutines/ Java Coroutines], and [https://github.com/offbynull/coroutines Coroutines]. * Platform-specific JNI mechanisms. These use JNI methods implemented in the OS or C libraries to provide the functionality to the JVM.{{citation needed|date=May 2014}} * Thread abstractions. Coroutine libraries which are implemented using threads may be heavyweight, though performance will vary based on the JVM's thread implementation. === JavaScript === Since [[ECMAScript 2015]], JavaScript has support for [[Generator (computer programming)|generators]], which are a special case of coroutines.<ref>{{cite web |url=https://es6-features.org/#GeneratorFunctionIteratorProtocol |title=ECMAScript 6: New Features: Overview and Comparison - Generator Function Iterator Protocol |website=es6-features.org |access-date=March 19, 2018 |archive-date=March 18, 2018 |archive-url=https://web.archive.org/web/20180318064130/https://es6-features.org/#GeneratorFunctionIteratorProtocol |url-status=usurped }}</ref> === Kotlin === [[Kotlin (programming language)|Kotlin]] implements coroutines as part of a first-party library. === Lua === [[Lua (programming language)|Lua]] has supported first-class stackful asymmetric coroutines since version 5.0 (2003),<ref>{{cite web |title=Lua version history |website=Lua.org |url=http://www.lua.org/versions.html |access-date=2023-04-24 |archive-date=2023-05-06 |archive-url=https://web.archive.org/web/20230506152024/https://www.lua.org/versions.html |url-status=live }}</ref> in the standard library ''coroutine''.<ref>{{cite web |last1=de Moura |first1=Ana LΓΊcia |last2=Rodriguez |first2=Noemi |last3=Ierusalimschy |first3=Roberto |title=Coroutines in Lua |url=http://www.lua.org/doc/jucs04.pdf |website=Lua.org |access-date=24 April 2023 |archive-date=19 March 2023 |archive-url=https://web.archive.org/web/20230319044538/http://www.lua.org/doc/jucs04.pdf |url-status=live }}</ref><ref>{{cite journal |last1=de Moura |first1=Ana LΓΊcia |last2=Rodriguez |first2=Noemi |last3=Ierusalimschy |first3=Roberto |title=Coroutines in Lua |journal=Journal of Universal Computer Science |date=2004 |volume=10 |issue=7 |page=901--924}}</ref> === Modula-2 === [[Modula-2]] as defined by [[Niklaus Wirth|Wirth]] implements coroutines as part of the standard SYSTEM library. The procedure NEWPROCESS() fills in a context given a code block and space for a stack as parameters, and the procedure TRANSFER() transfers control to a coroutine given the coroutine's context as its parameter. ===Mono=== The [[Mono (software)|Mono]] Common Language Runtime has support for continuations,<ref name="monoco">http://www.mono-project.com/Continuations {{Webarchive|url=https://web.archive.org/web/20101125045436/http://mono-project.com/Continuations |date=2010-11-25 }} Mono Continuations</ref> from which coroutines can be built. ===.NET Framework=== During the development of the [[.NET Framework]] 2.0, Microsoft extended the design of the [[Common Language Runtime]] (CLR) hosting APIs to handle fiber-based scheduling with an eye towards its use in fiber-mode for SQL server.<ref name="cbrumme-fibermode">http://blogs.msdn.com/cbrumme/archive/2004/02/21/77595.aspx {{Webarchive|url=https://web.archive.org/web/20071221020132/http://blogs.msdn.com/cbrumme/archive/2004/02/21/77595.aspx |date=2007-12-21 }} , Chris Brumme, [http://blogs.msdn.com/cbrumme/default.aspx cbrumme's WebLog] {{Webarchive|url=https://web.archive.org/web/20071211021110/http://blogs.msdn.com/cbrumme/default.aspx |date=2007-12-11 }}</ref> Before release, support for the task switching hook ICLRTask::SwitchOut was removed due to time constraints.<ref>{{Cite web|last=kexugit|title=Fiber mode is gone...|url=https://docs.microsoft.com/en-us/archive/blogs/dinoviehland/fiber-mode-is-gone|access-date=2021-06-08|website=docs.microsoft.com|date=15 September 2005|language=en-us|archive-date=2021-06-08|archive-url=https://web.archive.org/web/20210608142256/https://docs.microsoft.com/en-us/archive/blogs/dinoviehland/fiber-mode-is-gone|url-status=live}}</ref> Consequently, the use of the fiber API to switch tasks is currently not a viable option in the .NET Framework.{{Needs update|date=February 2023|reason=Coroutines have been a major part of mainstream .NET programming for years now.}} ===OCaml=== OCaml supports coroutines through its <code>Thread</code> module.<ref>{{cite web | title = The threads library | url = https://v2.ocaml.org/manual/libthreads.html | access-date = 2023-01-25 | archive-date = 2023-01-25 | archive-url = https://web.archive.org/web/20230125132306/https://v2.ocaml.org/manual/libthreads.html | url-status = live }}</ref> These coroutines provide concurrency without parallelism, and are scheduled preemptively on a single operating system thread. Since OCaml 5.0, [[Green thread|green threads]] are also available; provided by different modules. ===Perl=== * [https://metacpan.org/module/Coro Coro] Coroutines are natively implemented in all [[Raku (programming language)|Raku]] backends.<ref>{{cite web | title = RFC #31 | url = http://www.perl6.org/archive/rfc/31 | access-date = 2014-08-30 | archive-date = 2014-09-04 | archive-url = https://web.archive.org/web/20140904024226/http://www.perl6.org/archive/rfc/31 | url-status = live }}</ref> ===PHP=== * [https://www.php.net/manual/en/language.fibers.php Fibers] native since PHP 8.1 * [https://amphp.org/ Amphp] * [https://openswoole.com/ Open Swoole] *[https://symplely.github.io/coroutine/ Coroutine] implemented in a way that resembles [[Python (programming language)|Python]] functions, and some [[Go (programming language)|Go]], many [https://github.com/symplely/coroutine/tree/master/examples examples] showing there code converted with same number of lines and behavior. ===Python=== *[[Python (programming language)|Python]] 2.5 implements better support for coroutine-like functionality, based on extended generators ([https://www.python.org/dev/peps/pep-0342/ PEP 342]) *[[Python (programming language)|Python]] 3.3 improves this ability, by supporting delegating to a subgenerator ([https://www.python.org/dev/peps/pep-0380/ PEP 380]) *[[Python (programming language)|Python]] 3.4 introduces a comprehensive asynchronous I/O framework as standardized in [https://www.python.org/dev/peps/pep-3156/ PEP 3156], which includes coroutines that leverage subgenerator delegation *[[Python (programming language)|Python]] 3.5 introduces explicit support for coroutines with async/[[await]] syntax ([https://www.python.org/dev/peps/pep-0492/ PEP 0492]). *Since [[Python (programming language)|Python]] 3.7, async/await have become reserved keywords.<ref>{{cite web |url = https://docs.python.org/3/whatsnew/3.7.html#summary-release-highlights |title = What's New in Python 3.7 |access-date = 10 September 2021 |archive-date = 28 November 2019 |archive-url = https://web.archive.org/web/20191128153844/https://docs.python.org/3/whatsnew/3.7.html#summary-release-highlights |url-status = live }}</ref> *[http://eventlet.net/ Eventlet] *[https://github.com/python-greenlet/greenlet Greenlet] *[http://www.gevent.org gevent] *[http://www.stackless.com/ stackless python] ===Racket=== [[Racket (programming language)|Racket]] provides native continuations, with a trivial implementation of coroutines provided in the official package catalog. [https://pkgs.racket-lang.org/package/Coroutines Implementation by S. De Gabrielle] ===Ruby=== * [[Ruby (programming language)|Ruby]] 1.9 supports coroutines natively which are implemented as [http://rubydoc.info/stdlib/core/1.9.2/Fiber fibers], which are semi-coroutines.<ref>{{cite web|url=http://www.ruby-forum.com/topic/126011 |title=semi-coroutines |archive-date=October 24, 2007 |language=en |archive-url=https://web.archive.org/web/20071024123936/http://www.ruby-forum.com/topic/126011 }}</ref> * [http://liber.sourceforge.net/coroutines.rb An implementation by Marc De Scheemaecker] * [[Ruby (programming language)|Ruby]] 2.5 and higher supports coroutines natively which are implemented as [https://docs.ruby-lang.org/en/master/Fiber.html fibers] * [https://gist.githubusercontent.com/98-f355-f1/9929888ef734a829a6ee670beb88f82e/raw/2dea9bba72a88982ea752da1db13e9d5f2451abb/coroutines.rb An implementation by Thomas W Branson] ===Scheme=== Since [[Scheme (programming language)|Scheme]] provides full support for continuations, implementing coroutines is nearly trivial, requiring only that a queue of continuations be maintained. ===Smalltalk=== Since, in most [[Smalltalk]] environments, the execution stack is a first-class citizen, coroutines can be implemented without additional library or VM support. ===Tool Command Language (Tcl)=== Since version 8.6, the Tool Command Language supports coroutines in the core language. <ref>{{cite web |url=https://www.tcl.tk/man/tcl/TclCmd/coroutine.htm |title=coroutine manual page - Tcl Built-In Commands |publisher=Tcl.tk |access-date=2016-06-27 |archive-date=2016-10-02 |archive-url=https://web.archive.org/web/20161002010854/https://www.tcl.tk/man/tcl/TclCmd/coroutine.htm |url-status=live }}</ref> ===Vala=== [[vala (programming language)|Vala]] implements native support for coroutines. They are designed to be used with a Gtk Main Loop, but can be used alone if care is taken to ensure that the end callback will never have to be called before doing, at least, one yield. ===Assembly languages=== Machine-dependent [[assembly language]]s often provide direct methods for coroutine execution. For example, in [[MACRO-11]], the assembly language of the [[PDP-11]] family of minicomputers, the "classic" coroutine switch is effected by the instruction "JSR PC,@(SP)+", which jumps to the address popped from the stack and pushes the current (''i.e'' that of the '''next''') instruction address onto the stack. On [[VAX]]en (in [[VAX MACRO]]) the comparable instruction is "JSB @(SP)+". Even on a [[Motorola 6809]] there is the instruction "JSR [,S++]"; note the "++", as 2 bytes (of address) are popped from the stack. This instruction is much used in the (standard) 'monitor' [[ASSIST (computing)|Assist]] 09. ==See also== * [[Async/await]] * [[Pipeline (Unix)|Pipeline]], a kind of coroutine used for communicating between programs<ref name="EvolutionUnix" /> * [[Protothreads]], a stackless lightweight thread implementation using a coroutine like mechanism ==References== {{Reflist|refs= <ref name="KnuthVol1_1_4_5">{{Cite book | first = Donald Ervin | last = Knuth | series = The Art of Computer Programming | volume = 1 | title = Fundamental Algorithms | edition = 3rd | publisher = Addison-Wesley | year = 1997| isbn = 978-0-201-89683-1 | at = Section 1.4.5: History and Bibliography, pp. 229 | url = https://seriouscomputerist.atariverse.com/media/pdf/book/Art%20of%20Computer%20Programming%20-%20Volume%201%20(Fundamental%20Algorithms).pdf | url-status = live | archive-url = https://web.archive.org/web/20191021162138/https://seriouscomputerist.atariverse.com/media/pdf/book/Art%20of%20Computer%20Programming%20-%20Volume%201%20(Fundamental%20Algorithms).pdf | archive-date = 2019-10-21}}</ref> <!--pages = 229--> <ref name="Conway1963">{{Cite journal|last=Conway|first=Melvin E.|author-link=Melvin Conway|date=July 1963|title=Design of a Separable Transition-diagram Compiler|url=http://melconway.com/Home/pdf/compiler.pdf|journal=[[Communications of the ACM]]|publisher=ACM|volume=6|issue=7|pages=396–408|doi=10.1145/366663.366704|s2cid=10559786|issn=0001-0782|via=ACM Digital Library|archive-date=2022-04-06|access-date=2019-10-21|archive-url=https://web.archive.org/web/20220406043438/http://melconway.com/Home/pdf/compiler.pdf|url-status=live}}</ref> <ref name="KnuthVol1_1_4_2">{{Cite book | first = Donald Ervin | last = Knuth | series = The Art of Computer Programming | volume = 1 | title = Fundamental Algorithms | edition = 3rd | publisher = Addison-Wesley | year = 1997| isbn = 978-0-201-89683-1 | at = Section 1.4.2: Coroutines, pp. 193β200}}</ref> <!--pages = 193β200--> <ref name="EvolutionUnix">{{Cite book | first = Dennis M. | last = Ritchie | chapter = The evolution of the unix time-sharing system | series = Lecture Notes in Computer Science | title = Language Design and Programming Methodology | url = http://cm.bell-labs.com/cm/cs/who/dmr/hist.html | year = 1980 | volume = 79 | pages = 25β35 | doi = 10.1007/3-540-09745-7_2 | isbn = 978-3-540-09745-7 | s2cid = 571269 | access-date = 2011-01-26 | archive-date = 2015-04-08 | archive-url = https://web.archive.org/web/20150408054606/http://cm.bell-labs.com/cm/cs/who/dmr/hist.html }}</ref> <ref name="Perlis1982_6">{{Cite journal | last1 = Perlis | first1 = Alan J. | doi = 10.1145/947955.1083808 | title = Epigrams on programming | journal = ACM SIGPLAN Notices | volume = 17 | issue = 9 | pages = 7β13 |date=September 1982 | s2cid = 20512767 | url = http://www-pu.informatik.uni-tuebingen.de/users/klaeren/epigrams.html | archive-url = https://web.archive.org/web/19990117034445/http://www-pu.informatik.uni-tuebingen.de/users/klaeren/epigrams.html | archive-date = January 17, 1999 | quote = 6. Symmetry is a complexity reducing concept (co-routines include sub-routines); seek it everywhere | doi-access = free }}</ref> <ref name="MertzIBM">{{cite web|url=http://www.ibm.com/developerworks/library/l-pygen.html |title=Generator-based State Machines |work=Charming Python |first=David |last=Mertz |publisher=IBM developerWorks |date=July 1, 2002 |access-date=Feb 2, 2011 |archive-url=https://web.archive.org/web/20090228140658/http://www.ibm.com/developerworks/library/l-pygen.html |archive-date=February 28, 2009 }}</ref> }} ==Further reading== * {{cite journal|citeseerx=10.1.1.58.4017|author1=Ana Lucia de Moura|author2=Roberto Ierusalimschy|title=Revisiting Coroutines|journal=ACM Transactions on Programming Languages and Systems|volume=31|issue=2|pages=1β31|year=2004|doi=10.1145/1462166.1462167|s2cid=9918449}} ==External links== * [[Simon Tatham]]'s C oriented [http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html comprehensive introduction to coroutines] * [http://www.softpanorama.org/Lang/coroutines.shtml Softpanorama coroutine page]{{snd}}contains extensive assembler coroutines links [[Category:Concurrent computing]] [[Category:Subroutines]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:As of
(
edit
)
Template:Citation needed
(
edit
)
Template:Cite book
(
edit
)
Template:Cite conference
(
edit
)
Template:Cite journal
(
edit
)
Template:Cite web
(
edit
)
Template:Dead link
(
edit
)
Template:Div col
(
edit
)
Template:Div col end
(
edit
)
Template:External links
(
edit
)
Template:Further
(
edit
)
Template:Main
(
edit
)
Template:Needs update
(
edit
)
Template:Primary source inline
(
edit
)
Template:Reflist
(
edit
)
Template:Short description
(
edit
)
Template:Snd
(
edit
)
Template:Webarchive
(
edit
)