What is boost :: asio :: spawn?

I cannot form a mental picture of how the flow of control with the calf occurs.

  • When I call spawn(io_service, my_coroutine) , does it add a new handler to the io_service , which ends the call to my_coroutine ?

  • When I call the async function inside coroutine, passing it my yield_context , does it pause the coroutine until the async operation completes?

      void my_coroutine (yield_context yield)
     {
       ...
       async_foo (params ..., yield);
       ... // control comes here only once the async_foo operation completes
     } 

I do not understand how we avoid expectations. Say, if my_coroutine serves a TCP connection, how do other instances of my_coroutine while being called while on a particular instance paused, waiting for async_foo complete?

+5
source share
1 answer

In short:

  • When spawn() is called, Boost.Asio does some configuration work, and then uses strand to dispatch() internal handler that creates a coroutine using a function provided by the user as an entry point. Under certain conditions, the internal handler may be called in the spawn() call, and in other cases it will be sent to io_service for a deferred call.
  • The corporation pauses until the operation completes and the completion handler is called, io_service is destroyed, or Boost.Asio detects that the coroutine has been suspended without the possibility of resuming it, after which Boost.Asio will destroy the coroutine.

As mentioned above, when calling spawn() Boost.Asio does some configuration work, and then uses strand to dispatch() internal handler that creates a coroutine using a function provided by the user as an entry point. When the yield_context is passed as an asynchronous operation handler, Boost.Asio will immediately after initializing the asynchronous operation with the completion handler, which will copy the results and resume the coroutine. The previously mentioned thread belongs to the coroutine, which is used to guarantee the return of income before renewal. Consider a simple example demonstrating spawn() :

 #include <iostream> #include <boost/asio.hpp> #include <boost/asio/spawn.hpp> boost::asio::io_service io_service; void other_work() { std::cout << "Other work" << std::endl; } void my_work(boost::asio::yield_context yield_context) { // Add more work to the io_service. io_service.post(&other_work); // Wait on a timer within the coroutine. boost::asio::deadline_timer timer(io_service); timer.expires_from_now(boost::posix_time::seconds(1)); std::cout << "Start wait" << std::endl; timer.async_wait(yield_context); std::cout << "Woke up" << std::endl; } int main () { boost::asio::spawn(io_service, &my_work); io_service.run(); } 

The above example outputs:

 Start wait Other work Woke up 

Here is an attempt to illustrate the execution of an example. Ways in | indicate an active stack,: indicates a paused stack, and arrows are used to indicate a transfer of control:

 boost::asio::io_service io_service; boost::asio::spawn(io_service, &my_work); `-- dispatch a coroutine creator into the io_service. io_service.run(); |-- invoke the coroutine creator | handler. | |-- create and jump into | | into coroutine ----> my_work() : : |-- post &other_work onto : : | the io_service : : |-- create timer : : |-- set timer expiration : : |-- cout << "Start wait" << endl; : : |-- timer.async_wait(yield) : : | |-- create error_code on stack : : | |-- initiate async_wait operation, : : | | passing in completion handler that : : | | will resume the coroutine | `-- return <---- | |-- yield |-- io_service has work (the : : | &other_work and async_wait) : : |-- invoke other_work() : : | `-- cout << "Other work" : : | << endl; : : |-- io_service still has work : : | (the async_wait operation) : : | ...async wait completes... : : |-- invoke completion handler : : | |-- copies error_code : : | | provided by service : : | | into the one on the : : | | coroutine stack : : | |-- resume ----> | `-- return error code : : |-- cout << "Woke up." << endl; : : |-- exiting my_work block, timer is : : | destroyed. | `-- return <---- `-- coroutine done, yielding `-- no outstanding work in io_service, return. 
+17
source

All Articles