问题
I have a method that gets called via a third party from IO service. My method is supposed to return a boolean. However, I need to post another task to the same IO service, and wait for it to complete before I know the result. How can I return control to the IO loop while I wait for the other task to finish?
(I can add multiple threads, but then there could be multiple calls to my methods, and you'd still end up with a deadlock)
Call graph before:
<thread> io_service third_party my_stuff
| | | |
|---run----->| | |
| |-->some_posted_method-->| |
| | |--callback-->|
| | |<--boolean---|
| |(next task) | |
| | | |
Call graph preferred:
<thread> io_service third_party my_stuff
| | | |
|---run----->| | |
| |-->some_posted_method-->| |
| | |--callback-->|
| |<----some_way_to_return_control-------|
| |(next task) | |
| |--------some_kind_of_resume---------->|
| | |<--boolean---|
| | | |
回答1:
"third_party" should call "my_stuff" asynchronously, specify a handler that will continue as soon as result is ready, and return control to io_service
. "third_party" is a little bit worrying here as it's possible you cannot modify it or it's not desirable.
Another approach would be to use another io_service
instance for "my_stuff": "my_stuff" interface would be synchronous but implementation would use io_service
in the same or another thread to accomplish its task. Never tried this but I don't see any problem from what I know about Boost.Asio.
回答2:
Like Tanner Sansbury mentioned, you can call poll_one
from your event handler, and it will execute the available handlers.
Mind that you have to call poll_one
, since poll
is not guaranteed to return if new handlers keep being added. And since poll_one
may not have a handler ready to execute yet, you may want to add a sleep to prevent busy waiting. My code ended up like this:
while( !syncDone ) {
boost::system::error_code ec;
int handlersExecuted = ioService.poll_one(ec);
if( ec ) {
//Not sure what error there could be, log it
}
if( 0 == handlersExecuted ) {
std::this_thread::sleep_for(
std::chrono::milliseconds(10)
);
}
}
来源:https://stackoverflow.com/questions/39911668/boostasioio-service-return-control-to-io-services-run-while-waiting-for-fu