5 ms·
C++ Coroutines Advanced: Converting std:future to asio:awaitable
- xialeistudio 1y agoIn modern C++ development, coroutines have brought revolutionary changes to asynchronous programming. However, when using boost::asio or standalone asio, we often encounter scenarios where we need to convert traditional std::future<T> to asio::awaitable<T>. This article will detail an efficient, thread-safe conversion method.
- userbinator 1y agoDid you just copy-paste the first paragraph of the article.
- vlovich123 1y agoIt's literally his article.
- tgv 1y agoIf you post to HN, you can choose between a text or a url. When you pick url, you can add some text, but it's added as a comment. I guess that's what happened.
- mgaunard 1y agoSo the solution is to have a thread waiting on the future. Technically you'd need a thread per future, which is not exactly scalable. The article uses a pool which has its own problems. The article even mentions an arguably better approach (check on a timer), but for some reasons claims it is worse. Those integrations are not exactly good designs regardless; simply don't use std::future is the solution, and use non-blocking async mechanisms that can cooperate on the same thread instead. Standard C++ has one albeit somewhat overcomplicated, senders and receivers. Asio also works.
- gpderetta 1y agoBoost also has a better future that at least allows composition. But yes, do not use std::future except for the most simple tasks.
- Davidbrcz 1y agoI work with C++, but the amount of don't use standard feature X because reason' is crazy.
- account42 1y agoIt is a bit sad to see this for newer features. Maybe the committee should re-evaluate how quickly new designs are pushed into the standard and allow for a bit more time for evaluation. Moving fast makes sense when it's ok to break thinks, not so much when you need to support the result forever.
- m-schuetz 1y agoOn the contrary, I think they should move faster and provide more convenience functions that are "good enough" for 90% of use cases. For power users, there will always be a library that addresses domain-specific issues better than the standard could ever hope to. Instead, the comitee attempts to work towards perfect solutions that don't exist, and ends up releasing overengineered stuff that is neither the most convenient, performant, nor efficient solution. Like <random>
- pjmlp 1y agoAnd who gets to implement those ideas faster, many of which were never implemented before being added into the standard in first place? The surviving three compilers are already lagging as it is, none of them is fully 100% C++20 compliant, C++23 might only become 100% on two of them, lets see how C++26 compliance turns out to be, meanwhile C++17 parallel algorithms are only fully available in one of them, while the two other ones require TBB and libstdc++ to actually make use of them.
- flakes 1y agoSeems prone to deadlocking- I would avoid making the thread-pool globally scoped, and instead provide it as arguments to the helper methods.
- usrnm 1y agoEvery time I read an article like this I thank the day when I switched from C++ to go. I know why C++ is like this, I understand all the hard work that went into evolving it over 40 years, but I simply refuse to deal with all this stuff anymore. I have better things to worry about in my life.
- IshKebab 1y agoYeah... I used C++ coroutines a bit and they're super powerful and can do anything you want... But... I mean look at how complex co_await is: https://en.cppreference.com/w/cpp/language/coroutines.html#co_await https://en.cppreference.com/w/cpp/language/coroutines.html#c... It does about 20 different steps with a ton of opportunities for overloading and type conversion. Insanely complicated! And they kept up the pattern of throwing UB everywhere: > Falling off the end of the coroutine is equivalent to co_return;, except that the behavior is undefined if no declarations of return_void can be found in the scope of Promise. Why?? Clearly they have learnt nothing from decades of C++ bugs. Hopefully Rust gets coroutines soon...
- Yoric 1y agoOut of curiosity, what would you use coroutines for, in Rust? My personal use was clearly `async`/`await`, and this landed quite some time ago.
- IshKebab 1y agoFor stimulus generation for SystemVerilog tests. I think you might be able to use `async`/`await` for that but I'm not 100% sure - I haven't tried.
- jcelerier 1y ago> I mean look at how complex co_await is it doesn't look meaningfully more complex than C#'s spec (which has absolutely horrendous stuff like :throw-up-emoji: inheriting from some weird vendor type like "System.Runtime.CompilerServices.INotifyCompletion")? https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#1298-await-expressions https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...
- monkeyelite 1y agoWho is asking for C++ coroutines and how did we get to C++20 without it?
- quietbritishjim 1y agoI'm interested in this too. Coroutines in Python are fantastically useful and allow more reliable implementation of networking applications. There is a complexity cost to pay but it's small and resolves other complexity issues with using threads instead, so overall you end up with simpler code that is easier to debug. "Hello world" (e.g., with await sleep(1) to make it non-trivially async) is just a few lines. But coroutines in C++ are so stupendously complicated I can't imagine using them in practice. The number of concepts you have to learn to write a "hello world" application is huge. Surely just using callback-on-completion style already possible with ASIO (where the callback is usually another method in the same object as the current function), which was already possible, is going to lead to simpler code, even if it's a few lines longer than with coroutines? Edit: We have a responsibility as senior devs (those of us that are) to ensure that code isn't just something we can write but that other can read, including those that don't spend their spare time reading about obscure C++ ideas. I can't imagine who in good faith thinks that C++ coroutines fall into this category.
- rhaen 1y agoThe majority of the complexity is in the library/executor, rather than in callers. We have an implementation at my company which is now being widely rolled out and it's a pretty dramatic readability win to convert callback based codes to nearly-straight line coroutine code.
- quietbritishjim 1y agoThat's very promising. Boost ASIO seemed to be the first serious coroutine library for C++ and that seemed complex to use (I'm saying that as a long-time user of its traditional callback API) but that's perhaps not surprising given that it had to fit with its existing API. But then there was a library (I forget which) posted to HN that was supposed to be a clean fresh coroutine library implementation and that still seems more complex than ASIO and callbacks - it seemed like you needed to know practically every underlying C++ coroutine concept. But maybe there just needed to be time for libraries to mature a bit.