io_context
contains the state required to run the event-loop in the thread using platform-specific calls, such as select
or epoll
. Normally, there can be one (active) event loop per thread.
This component runs the event-loop invoking low-level platform-specific calls to acquire operating-system events such as socket readiness, timer, signal, idle and deliver them to user-registered callbacks in portable fashion.
It doesn't do any I/O, rather it invokes the callbacks when I/O can be done, e.g. network data has arrived and the socket is ready for read. The callbacks are expected to do their processing/non-blocking-I/O promptly and return in order to not block the event-loop in the thread.
Such a component is sometimes called an operating-system event demultiplexer because calls like select
and epoll
report file descriptor readiness, timeout and signal events by returning different values, which must be examined first (along with errno
for signals) to distinguish what events it has reported. This examination of the return value to detect the event type followed by calling the corresponding event handler is demultiplexing of different event types reported by one syscall. These syscalls block the calling thread (to avoid burning CPU cycles / draining batteries) until one of these events happens, and that's why the caller has to demultiplex the return value to tell what kind of event is reported.
See Basic Boost.Asio Anatomy for more details.
Other popular event loops are libevent
and libuv
The C10K problem is old but quite instructive on the subject of async I/O.
C++20 coroutines introduce a new programming model, which has benefits of being simpler to write and read and it mitigates callback hell inherent in non-blocking I/O code. See full details in Boost.Asio supports coroutines.
Async/coroutines I/O model is cheaper/easier to code for. It is still the same event-loop invoking the callbacks underneath, but now these callbacks do the coroutine state create/save/load/destroy to implement the async programming model for the user.