Skip to main content

Coroutine

Pronunciation
KOH-roo-teen
Updated 3 min read

Share this page

Send the link, quote the definition with a link back, or show it as a card on your own site.

https://softwaredictionary.org/terms/coroutine

In short

A coroutine is a function that can pause partway, hand control back, and later resume where it stopped, so many tasks can take turns on just a few threads.

What is a coroutine?

A normal function runs from start to finish once it is called. A coroutine can suspend itself partway, at points it marks explicitly, and be resumed later with all its local variables intact. Melvin Conway coined the term in 1958, and the idea now sits underneath generators, async/await and Kotlin's coroutines.

Coroutines use cooperative multitasking: each one runs until it chooses to pause, typically while it waits for a network response or a timer, and a scheduler, often an event loop, then runs another coroutine that is ready. Switching only saves a little state, with no operating system involved, so a program can run thousands or even millions of coroutines on a handful of threads. In Python, async def defines a coroutine and each await is a point where it may pause; Kotlin marks pausable functions with suspend, C++20 added co_await and co_yield, and Lua has coroutine.yield.

Picture a chess master playing many boards at once: she makes a move, walks to the next board while that opponent thinks, and later returns to find each game exactly as she left it. Coroutines power servers that juggle many network connections, generators that produce values one at a time, game scripts that wait a few frames, and interfaces that must keep responding while data loads.

Coroutines are often confused with threads. The operating system schedules threads preemptively, meaning it can interrupt them at any instruction, and threads can run in parallel on several cores; coroutines switch only where they choose to, so the code between two pauses never interleaves with other coroutines on the same thread. The flip side is that a coroutine doing long CPU work without pausing blocks everything else on its thread. Async/await is the syntax many languages use for coroutines, while Go's goroutines, despite the name, behave more like lightweight threads.

Key takeaways

  • A coroutine can pause partway and later resume with its local state intact.
  • Coroutines give up control voluntarily, which is called cooperative multitasking.
  • They are far cheaper than threads, so a program can run thousands of them.
  • Python's async functions and generators and Kotlin's suspend functions are all forms of coroutines.
  • A coroutine that never pauses blocks every other coroutine on its thread.

Example

Two coroutines taking turns on one thread (Python asyncio)python
import asyncio

async def download(name, seconds):
    print(f"{name}: started")
    await asyncio.sleep(seconds)  # pause here; the event loop runs the other one
    print(f"{name}: finished")    # resume later with every local variable intact
    return name

async def main():
    # Both coroutines run on a single thread, taking turns
    results = await asyncio.gather(download("a", 2), download("b", 1))
    print(results)  # ['a', 'b'] after about 2 seconds, not 3

asyncio.run(main())

Readers ask

What is the difference between a coroutine and a thread?

The operating system schedules threads, can interrupt them at any moment and can run them in parallel. Coroutines are scheduled by the program, switch only at the points they choose and use far less memory, so you can run many more of them. Many runtimes run coroutines on top of a small pool of threads.

Are goroutines coroutines?

Not quite. Goroutines are lightweight threads managed by the Go runtime: since Go 1.14 the runtime can interrupt them, and they run in parallel across CPU cores. The name is a play on the word coroutine.

Is async/await the same as coroutines?

Async/await is syntax for writing coroutines. In Python, calling an async def function returns a coroutine object, and each await is a point where it can pause; C#, JavaScript and Rust turn async functions into similar pausable state machines.

See also

Sources

Spotted a mistake or something missing on this page?Suggest an edit

More

Settings