When I use spawn to start a new stackfull coroutine in a coroutine, valgrind says a lot of using uninitialised value(valgrind output).
Then I use io_service.post to invoke a handler,and start a new stackfull coroutine in it, every thing seems fine.
I have searched and read some documents, but can't find something about how to create a new stackfull coroutine safely in a stackfull coroutine.
Here is the code:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/system_timer.hpp>
#include <chrono>
using namespace std;
int main()
{
auto use_post = false;
boost::asio::io_service io_service;
boost::asio::spawn(io_service,
[&io_service, &use_post](boost::asio::yield_context yield){
if(use_post){
io_service.post([&io_service]{
boost::asio::spawn(io_service, [&io_service](boost::asio::yield_context yield){
boost::asio::system_timer timer(io_service);
timer.expires_from_now(std::chrono::seconds(1));
timer.async_wait(yield);
cout << "Sleep 1 second" << endl;
});
});
}
else{
boost::asio::spawn(io_service, [&io_service](boost::asio::yield_context yield){
boost::asio::system_timer timer(io_service);
timer.expires_from_now(std::chrono::seconds(1));
timer.async_wait(yield);
cout << "Sleep 1 second" << endl;
});
}
boost::asio::system_timer timer(io_service);
timer.expires_from_now(std::chrono::seconds(2));
timer.async_wait(yield);
cout << "Sleep 2 seconds" << endl;
});
io_service.run();
return 0;
}
set true to use_post
variable, new stackfull coroutine will be started by post + spawn.
Maybe I don't read the documents carefully, i can't find any thing usefull in Boost.Asio C++ Network Programming
, N4045
and boost asio document.
It is safe.
Boost.Asio's first-class support for Boost.Coroutine is a thin facade with two notable behaviors:
strand
for their execution context. This guarantees the coroutine will not be resumed before it has yielded.In the example code above, the
spawn(io_service&)
overload causes the resulting coroutine to have its ownstrand
. As a result, if multiple threads are running theio_service
, each of the coroutines may run in parallel, but are not guaranteed to do so. On the other hand, if one uses thespawn(yield_context)
overload, the new coroutine will have the same execution context (i.estrand
) as the calling coroutine, preventing parallel execution.