Subroutine vs Coroutine
- Coroutines is a more generalized form of subroutines.
- can be entered, exited, and resumed at many different points.
- can pause execution and yield control back to the caller or another coroutine. The caller can then resume the coroutine when appropriate.
- used for cooperative multitasking and are often compared to fibers, lightweight threads and green threads
- invoked once and executes until it completed
- can be translated to a coroutine which does not call yield
Coroutines use cases:
- data structure iterators
- event-driven code without the inversion of control
- cooperative multitasking
- concurrency frameworks such as actors, async-await and dataflow networks
- expressing asynchrony, and better composition of asynchronous systems
- capturing continuations
- expressing backtracking algorithms
- AI agents such as behavior trees
- both of these can yield multiple times, suspending their execution and allowing re-entry at multiple entry points
- also a generalisation of subroutines, but are more limited than coroutines
- sometimes referred to as “semicoroutines”, a more limited form of coroutine that may only yield to its caller.
- primarily used to simplify the writing of iterators, the yield statement in a generator does not specify a coroutine to jump to, but rather passes a value back to a parent routine.
- able to control where execution continues immediately after they yield, while generators cannot, instead transferring control back to the generator's caller.
The difference between coroutines and threads is that rather than have the OS schedule execution of the various threads, the developer is free to schedule the execution of the coroutines. This is why they may be referred to as lightweight threads or green threads.
- async and await