chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.96k stars 1.22k forks source link

c++20 stackless coroutine #256

Open huyuguang opened 7 years ago

huyuguang commented 7 years ago

Now the c++ 20 coroutine TS has been supported by visual studio 2017 and clang 5.0, would you please write some sample codes to show how to use the asio + cpp20_coroutine?

vinniefalco commented 7 years ago

Stackless coroutines have nothing to do with "real" coroutines such as the ones from Boost.Context or the Coroutines TS. They do not depend on the version of C++, as they are implemented entirely with macros and one simple class.

akoolenbourke commented 7 years ago

The co_await branch of ASIO has c++20 coroutine experimental support. To get it working with the master branch of ASIO you will need to fix the compiler errors and convert to some of the newer ways of doing things (TS vs Boost/ASIO). I have done this and it's working "well" however I am unsure if there's a better way to do ASIO+coroutines in general as currently all async operations create a coroutine frame, which is another heap alloc (At least on MSVC 2017 in the context I'm using it in). In additional each coroutine that uses co_await on an ASIO operation has an additional post() called to destroy the awaitable. This is not so bad if you run a single coroutine for all your work but if you want to start nesting them (Which ASIO coroutines supports) inside a main coroutine loop (as I do) then things get a little more expensive.

I did some benchmarking and whilst with a thread or two servicing tunnelling requests was about 10% slower than callbacks, when you amp up the number of incoming connections and workers this seemed to disappear but I haven't investigated as to why this is yet when coroutines are certainly doing more "work" than callbacks.

Personally I am tempted to go ahead and use ASIO+ TS coroutines in our product but the overhead I've seen does make me wonder if I'll hit some big issues when I'm at scale and start building a non-trivial application. Some more guidance from experienced users would be great but I have yet to find any. All this is making me think it might be best to take a "wait and see" approach and put up with the pain that is callbacks and state management etc.

BTW: You can provide operator new/delete for awaitable so you can provide some pooling. I hope there is a way with C++20 coroutines to integrate a little more efficiently with the networking TS when these things get to standard.