Coroutine usages for asynchronous programming in C
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
C++20 coroutines let you write asynchronous code that reads like synchronous code. A coroutine is a function that can suspend execution at specific points (co_await, co_yield, co_return) and resume later without blocking a thread. This eliminates callback nesting and manual state machines for async I/O, generators, and lazy sequences. Unlike std::async or std::thread, coroutines do not create new threads — they provide cooperative multitasking on existing threads.
Basic Coroutine Structure
A function becomes a coroutine when it uses co_await, co_yield, or co_return. The compiler transforms it into a state machine that can be paused and resumed.
co_await: Asynchronous Operations
co_yield: Generators
Generators produce values lazily — each value is computed on demand:
The generator produces Fibonacci numbers one at a time, computing each only when next() is called.
Async I/O Pattern
The coroutine suspends at co_await, the I/O operation runs asynchronously, and the coroutine resumes when data is ready — all without blocking a thread.
Coroutines vs Callbacks vs Threads
Coroutines linearize async code. Error handling works with normal try/catch instead of error callbacks.
Lazy Evaluation with Coroutines
Library Support
cppcoro provides task<T>, generator<T>, when_all, when_any, and other utilities that make C++20 coroutines practical.
Common Pitfalls
- No standard library Task type: C++20 provides the coroutine machinery (
co_await,co_yield,co_return) but no standardTaskorGeneratortype. You must write your own or use a library likecppcoro. - Dangling coroutine handles: If you destroy a
coroutine_handlewhile it is suspended, any references to stack variables in the coroutine become invalid. Always ensure proper lifetime management. - Coroutines are not threads:
co_awaitdoes not create a new thread. If no executor schedules the resume on another thread, the coroutine resumes on whatever thread callshandle.resume(). For true parallelism, integrate with a thread pool. - Heap allocation: Coroutine state is allocated on the heap by default. For performance-critical code, the compiler can sometimes elide this allocation (HALO optimization), but it is not guaranteed.
- Compiler support varies: GCC, Clang, and MSVC all support C++20 coroutines but with varying levels of optimization and debugging support. Test on your target compiler.
Summary
- C++20 coroutines use
co_await,co_yield, andco_returnto write suspendable functions - Generators (
co_yield) produce values lazily without computing the entire sequence upfront - Async I/O (
co_await) eliminates callback nesting by letting you write linear async code - Coroutines do not create threads — they provide cooperative multitasking on existing threads
- Use a library like
cppcorofor practical Task and Generator types - The promise_type pattern lets you customize suspension, return values, and exception handling
Related reading
- Correct way to create a new task and call asynchronously a web api c
- Correctly accessing Core Data from another thread using the new Asynchronous Task in Swift
- Couchbase mobile replication through REST-API
- CouchDB data synchronization
- Create multiple Instances of Caffe - C
- Creating all possible k combinations of n items in C
- CouchDB Filtered Replication
- CountDownLatch in HandlerThread locking on await in Android
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.