Stackless and Stackful Coroutines

Riguz留言 | 贡献2025年7月30日 (三) 01:26的版本 →‎Stackless Coroutines
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
Language Coroutine Type
Python async/await Stackless
Python yield Stackless
JavaScript async/await Stackless
JavaScript function* (Generators) Stackless
C++ std::coroutine (co_await, co_yield) Stacked
C# async/await Stackless
Kotlin suspend functions Stackless
Lua coroutine.create, coroutine.resume Stacked
Ruby Fiber.new Stacked
Node.js async/await Stackless
Go goroutines Stackless

Stacked Coroutines

These are coroutines that rely on the program's call stack for managing their state.

When a coroutine calls another coroutine, the caller's state is saved on the stack, and the callee's state is pushed onto the stack. This allows for a natural nesting of coroutine calls.

Example: Traditional thread-based systems or languages like C++ with stackful coroutines.

Advantages: Easier to implement and debug because they follow the natural call stack. Disadvantages: Limited by the size of the call stack and can be less efficient in terms of memory usage.

Stackless Coroutines

These coroutines do not use the program's call stack to manage their state. Instead, they maintain their own state explicitly.

The state of the coroutine is stored in a separate data structure, and the coroutine's execution is resumed from this state.

Example: Python's asyncio or JavaScript's async/await.

Advantages: More flexible and efficient in terms of memory usage. They can scale better for large numbers of coroutines. Disadvantages: More complex to implement and debug since they don't follow the natural call stack.