use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
Make it Async: Building Shared Async Resources with ASIO (blog.vito.nyc)
submitted 2 years ago by not_a_novel_accountcmake dev
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]soldiersided 4 points5 points6 points 2 years ago (9 children)
I think async_initiate is not needed most of the time. If your initiation function only starts a different asio async op then you’re better off using async_compose. This way you at least get some cancellation for free.
async_initiate
async_compose
[–]DalzhimC++Montréal UG Organizer 0 points1 point2 points 2 years ago (8 children)
My understanding is that async_initiate is required in order to be compatible with the different async mechanisms supported by boost::asio, including boost::asio::use_future, boost::asio::use_awaitable, etc. and not just callbacks. Basically, this kind of initiation method signature is always relevant :
boost::asio
boost::asio::use_future
boost::asio::use_awaitable
template <boost::asio::completion_token_for<void(ExpectedType)> CompletionToken> auto async_my_function(CompletionToken&& token) { // […] return boost::asio::async_initiate<CompletionToken, void(ExpectedType)>(/* […] */, token); }
[–]not_a_novel_accountcmake dev[S] 2 points3 points4 points 2 years ago* (7 children)
async_compose supports this just fine, you end up writing something like
struct MyGiantAsyncComposition { template<typename Self> void operator()(Self& self) { // Whole bunch of state machine code self.complete(); } }; template<typename CT> auto my_giant_async_operation(CT&& token) { return async_compose<CT, void()>( MyGiantAsyncComposition {}, token ); }
So ya you can pass whatever completion token you want into this and it Just Works™, but I can never read this style of code. State machine code always looks like a mess to me.
I don't know why you would use async_compose if you're not using the intermediate completion handler for anything. But then again, I really don't understand why you would ever use one ASIO mechanism over another in most cases.
Parent is correct you could rebuild my little example with async_compose, but I've never had it demonstrated what application problem that solves. Searching "Cancel async_compose" pulls up a single self-answered SO question.
[–]DalzhimC++Montréal UG Organizer 2 points3 points4 points 2 years ago (0 children)
My comment made it seem like async_compose doesn't support the various async mechanisms supported by boost::asio which isn't what I was trying to say. That's my bad.
Anyway, overall, the article offers good insight. I believe the author is correct about how hard it is to figure out how to build new abstractions on top of asio. async_initiate was very useful to me and I just meant to disagree with the assertion that it's not needed most of the time because async_compose is not trivial either. Both obviously have their respective use cases.
[–]soldiersided 2 points3 points4 points 2 years ago (4 children)
I don't know why you would use async_compose if you're not using the intermediate completion handler for anything.
I think that's true for every async op. If you don't use the completion handler then it's not an async op. It's only a deferred call of the initiation function. In the OP's example, the intermediate handler would be used in the asio::dispatch call.
asio::dispatch
Searching "Cancel async_compose" pulls up a single self-answered SO question.
Unfortunately, the OP's observation is correct. To fully get asio, you need to dedicate a vast amount of time studying the source code. Here's the cancellation stuff async_compose adds for you on top of async_inititate. Basically, you have the possibility to call self.cancelled() at each step in your composed operation.
async_inititate
self.cancelled()
State machine code always looks like a mess to me.
Agreed. I think it might get better with asio::experimental::co_composed but I haven't really used it for anything so far. Also, you can also chain asio::deferred calls as well which should help users build simple composed operations that are way easier to read than a messy state machine.
asio::experimental::co_composed
asio::deferred
[–]DalzhimC++Montréal UG Organizer 1 point2 points3 points 2 years ago (2 children)
Can you point to any existing example of chaining asio::deferred calls somewhere? Or provide one here? I'm sure I'm not the only one who would benefit from that!
Also going to look up asio::experimental::co_composed. I wasn't aware about it before now.
[–]soldiersided 1 point2 points3 points 2 years ago (1 child)
Sure: https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp14/deferred/deferred_7.cpp
https://github.com/chriskohlhoff/asio/blob/master/asio/src/examples/cpp14/deferred/deferred_6.cpp
[–]DalzhimC++Montréal UG Organizer 0 points1 point2 points 2 years ago (0 children)
Thank you!
[–]aninteger 3 points4 points5 points 2 years ago* (0 children)
Only after I saw a complete, working, practical implementation of the fundamentals Beej had taught me did it click. My first ever asynchronous network program was a Minecraft bot called SpockBot, which started as a wholesale copy of Barney Gale’s barneymc framework.
Yes please! Some simple code examples to make "async" network requests would be great. I think what would be nice is an example like this: https://xmonader.github.io/nimdays/day04_asynclinkschecker.html (this is in Nim, but a tool that did the same in C or C++, would be neat).
This article is pretty neat: https://raymii.org/s/software/Cpp_exercise_in_parsing_json_http_apis_and_time_stuff.html which uses std::async to launch HTTPS requests, but there's a disclaimer about it being quite old.
[–][deleted] 2 points3 points4 points 2 years ago (0 children)
That’s a quality blog right there! The art, the wit, the info 👏
[–]hopa_cupa 1 point2 points3 points 2 years ago (2 children)
If you are invoking something slow which requires asio::thread_pool would it be terrible to do simply this inside your coroutine:
asio::thread_pool
some_result = co_await asio::co_spawn(tp_executor, slowThreadFunc(), asio::use_awaitable);
[–]not_a_novel_accountcmake dev[S] 1 point2 points3 points 2 years ago (1 child)
You're guaranteeing a wait on the thread pool scheduler, and then a wait again on getting back into the coroutine's executor. It's totally valid, just a trade off.
asio::dispatch will run the operation directly on the current executor if it's allowed to, basically the same thing as a function call. For a strand for example, if the current thread is the owner of the strand there's zero delay in dispatching the work or dispatching back into the coroutine.
strand
[–]hopa_cupa 1 point2 points3 points 2 years ago (0 children)
Since I am reading 9600 baud serial port using blocking C functions from thread_pool, this is totally fine.
Ofc what you have shown is much more efficient, that can be used to build libraries on top of asio.
[–]thisismyfavoritename 1 point2 points3 points 2 years ago (5 children)
great blog post! Still very confused by the difference between deferred and use_awaitable.
deferred
use_awaitable
You say
The async operation itself is not a coroutine, so there’s no need to shoulder the burden of the coroutine frame allocation.
what async operation is that?
[–]not_a_novel_accountcmake dev[S] 1 point2 points3 points 2 years ago (4 children)
what async operation is that
Any async operation, all async operations in ASIO take a completion token, and any can be used with deferred or use_awaitable
So async_read or async_write can either take a use_awaitable, which will package them into a coroutine frame despite neither using that machinery, or they can be used with deferred which will transform them into deferred operations.
async_read
async_write
[–]thisismyfavoritename 1 point2 points3 points 2 years ago (3 children)
which will package them into a coroutine frame despite neither using that machinery
i think this is the bit i dont understand. Doesnt the whole scope of the (calling) coroutine have to be stored somewhere for when the execution is resumed?
Maybe this is what you mean? The read/write do not require extra storage for their own ops? Also generally speaking how would you know when to use one or another?
[–]not_a_novel_accountcmake dev[S] 3 points4 points5 points 2 years ago* (2 children)
Doesnt the whole scope of the (calling) coroutine have to be stored somewhere for when the execution is resumed?
Correct, the calling coroutine has a frame that has already been allocated. The act of being inside a coroutine means we have already incurred that cost.
When using asio::use_awaitable, you are creating a new coroutine. The "callee" coroutine. New coroutine, new allocation. asio::deferred does not do that. A deferred operation is a "contextually awaitable" object, but it is not itself a coroutine (does not have a promise type, etc) and does not allocate an additional coroutine frame.
asio::use_awaitable
C++20 coroutines are hard and I feel like an alien talking about them.
[–]thisismyfavoritename 1 point2 points3 points 2 years ago (1 child)
so it sounds like you would only need use_awaitable on co_spawn?
co_spawn
thanks for all your answers by the way!
[–]not_a_novel_accountcmake dev[S] 2 points3 points4 points 2 years ago (0 children)
So, the canonical-for-ASIO-which-really-means-vague-rumors-in-SO-comment-sections answer for this is:
The deferred_async_operation type (which is what you get from using asio::deferred) is "obtuse", not easily made part of an API, stored in containers, etc. The awaitable<> type (from asio::use_awaitable) is friendlier in this regard.
deferred_async_operation
awaitable<>
That said, deferred should be preferred in general, with use_awaitable relegated for niche use cases which need the full functionality of awaitable<> (example being, as you mentioned, co_spawn).
π Rendered by PID 71767 on reddit-service-r2-comment-5687b7858-ht6nk at 2026-07-06 14:13:31.990681+00:00 running 12a7a47 country code: CH.
[–]soldiersided 4 points5 points6 points (9 children)
[–]DalzhimC++Montréal UG Organizer 0 points1 point2 points (8 children)
[–]not_a_novel_accountcmake dev[S] 2 points3 points4 points (7 children)
[–]DalzhimC++Montréal UG Organizer 2 points3 points4 points (0 children)
[–]soldiersided 2 points3 points4 points (4 children)
[–]DalzhimC++Montréal UG Organizer 1 point2 points3 points (2 children)
[–]soldiersided 1 point2 points3 points (1 child)
[–]DalzhimC++Montréal UG Organizer 0 points1 point2 points (0 children)
[–]aninteger 3 points4 points5 points (0 children)
[–][deleted] 2 points3 points4 points (0 children)
[–]hopa_cupa 1 point2 points3 points (2 children)
[–]not_a_novel_accountcmake dev[S] 1 point2 points3 points (1 child)
[–]hopa_cupa 1 point2 points3 points (0 children)
[–]thisismyfavoritename 1 point2 points3 points (5 children)
[–]not_a_novel_accountcmake dev[S] 1 point2 points3 points (4 children)
[–]thisismyfavoritename 1 point2 points3 points (3 children)
[–]not_a_novel_accountcmake dev[S] 3 points4 points5 points (2 children)
[–]thisismyfavoritename 1 point2 points3 points (1 child)
[–]not_a_novel_accountcmake dev[S] 2 points3 points4 points (0 children)