Включается опцией CMake NETLIB_ENABLE_COROUTINES=ON (по умолчанию, если toolchain поддерживает C++20 coroutines).
#include <netlib/execution/coroutine.hpp> // task, when_all, when_any, delay, spawn, generator
#include <netlib/net/coro.hpp> // awaitables + tcp/udp helpers + timeoutКаждый awaitable — struct с await_ready / await_suspend / await_resume, внутри вызывает async_* и coroutine_handle::resume.
Диаграмма последовательности: diagrams/coro_awaitable.puml.
@startuml sync_wait_pattern
participant Main
participant "io_thread" as IO
participant "thread_pool" as Pool
participant Loop as "event_loop"
Main -> Pool : thread_pool + scheduler
Main -> Loop : event_loop(sched)
Main -> IO : run loop.run_once в цикле
Main -> Pool : sync_wait(sched, my_task())
note over Main, Pool
task приостанавливается на co_await I/O;
completion приходит через schedule → pool
end note
@endumlМинимальный шаблон — examples/common/io_runner.hpp.
| API | Пример |
|---|---|
when_all(sched, a, b) |
сервер + клиент в одном sync_wait |
when_all(sched, vector<task<T>>) |
пул воркеров |
when_all(sched, t1, t2, t3) |
tuple из 3+ результатов |
when_any(sched, fast, slow) |
гонка |
with_timeout(sched, work, 5s) |
таймаут |
then(sched, t, fn) |
map после task |
spawn(sched, detached) |
фоновый echo-сервер в bench |
delay_async(sched, ms) |
пауза |
generator::next(sched) |
поток значений |
coro_tcp.hpp / tcp_coro.hpp:
read_string_async,read_exact_vec_asynctcp_echo_peer,tcp_serve_echo_oncetcp_echo_server_loop(acceptor, loop, &token)tcp_connect(+ overload сconnect_with_timeout)
udp_coro.hpp:
udp_send_string,udp_recv_stringudp_echo_once,udp_echo_loop
- Не использовать unnamed lambda-coroutine внутри
when_allvector — использовать именованныеtaskили отдельные функции. - Буфер
std::spanвasync_recv_from/read_someдолжен жить до завершения операции (стек вызывающей coroutine обычно OK). sync_waitиз колбэка reactor — запрещён (deadlock).