Skip to content

Asynchronous I/O and Coroutines ​

In the preceding chapters we built the infrastructure of concurrent programs with tools such as threads, mutex, atomic, and future. But when we face an I/O-bound scenario — say, a network server that has to handle thousands of connections at the same time — the traditional one-thread-per-connection model reveals a serious waste of resources. A thread doing nothing but waiting for I/O still holds on to memory and scheduling resources; we need a lighter-weight way to express "go do something else first, and come back once the I/O is done."

This chapter starts from the evolution of asynchronous programming paradigms, comparing the motivations and pain points of the three models — callbacks, future chains, and coroutines — so we can understand why coroutines are regarded as the right way to do async. We then dive into the internal machinery of C++20 coroutines — the compiler's state-machine transformation of coroutine functions, the allocation and destruction of the coroutine frame, and the lifetime management of coroutine_handle — and implement a complete generator from scratch to tie all the concepts together. Next we turn to the two major customization extension points of coroutines (promise_type and awaitables), plug coroutines into the operating system's I/O multiplexing, and build a coroutine-driven event loop. Finally, a complete coroutine Echo Server built in practice strings all of these knowledge points together.

In This Chapter ​

pdf-latest-4-g85128cc · 85128cc · 2026-10-05