I started trying to learn Boost::Asio by reading the documentation and example code. I found things difficult to understand, particularly because the model seemed similar to coroutines.
I then decided to learn about coroutines, starting with this cppcon talk. In the linked talk, the following line was given in an example of coroutine usage. The example was written in 2014, so the syntax may not match C 20 coroutines.
auto conn = await Tcp::connect.Read("127.0.0.1", 1337)
This feels similar to the stated goals of Boost::Asio. However, in the examples section of the Boost::Asio documentation, there is an example that mixes Boost::Asio and C 20 coroutines. (I do not yet understand this example.)
What is the relationship between Boost::Asio and coroutines? Do coroutines replace parts of Boost::Asio? If I am not doing networking, should I still use Boost::Asio? Where do std::async
and the senders/receivers proposal fit into all this?
CodePudding user response:
Q. What is the relationship between Boost::Asio and coroutines?
C 20 coroutines are one of the completion token mechanisms provided with any Asio compliant async API
Q. Do coroutines replace parts of Boost::Asio?
Not 1 on 1.
In practice people may feel a lot less need to write asio::spawn
(stackful) coroutines, because in practice the stackfulness is rarely required and makes the implementation (very) heavy in comparison. Also, up to Boost 1.81(?) asio::spawn
will still depend on Boost Coroutine (work is underway to remove that and implement the functionality directly on top of Boost Context).
Another where C 20 coroutines seem to remove friction is when providing a dual API (sync and async). I've heard people suggest that it is possible to implement the synchronous version in terms of the asynchronous version transparently. I'm not up to speed with the specifics of this pattern (and whether it is ready for production code yet).
Q. If I am not doing networking, should I still use Boost::Asio?
Should? No. But you may. In general, with c 20 coroutines you will want to use some library like cppcoro or indeed Asio. That's because no user-level library facilities have been standardized yet.
In Asio the interesting bits are:
experimental stuff like channels (
channel
andconcurrent_channel
), parallel_group, wait_for_{all,one,any}the general purpose facility
coro
which has a lot of flexibility. You could see it as the most useful 80% of cppcoro butall in one relatively simple class template:
coro<T>
-> simple generatorcoro<T(U)>
-> generator with inputcoro<void, T>
task producing aT
integrated with Asio executors
This documentation is a pretty decent introduction¹, especially when you're familiar with concepts from other libraries/languages.
Q. Where do std::async and the senders/receivers proposal fit into all this?
I'm not sure. I seem to remember Chris Kohlhoff wrote that proposal. The concept may be lurking under the channel
/deferred
abstractions in Asio already.
¹ Hat tip @klemensmorgenstern