问题
I am using (single threaded) a boost::asio:io_service
to handle a lot of tcp connections. For each connection I use a deadline_timer to catch timeouts. If any of the connections times out, I can use none of the results of the other connections. Therefore I want to completely restart my io_service. I thought that calling io_service.stop()
would allow "finished" handlers in the queue to be called and would call handlers in the queue with an error.
However it looks like the handlers remain in the queue and therefore calling io_service.reset()
and later io_service.run()
brings the old handlers back up.
Can anyone confirm that the handlers indeed remain in the queue even after io_service.stop()
is called. And if so, what are the possibilities to completly reset the io_service, e.g. remove all queued handlers?
回答1:
io_service::stop() and io_service::reset() only control the state of the io_service
's event loop; neither affect the lifespan of handlers scheduled for deferred invocation (ready-to-run) or user-defined handler objects.
The destructor for io_service
will cause all outstanding handlers to be destroyed:
- Each service object associated with the
io_service
will have itsshutdown_service()
member function invoked. Per the Service type requirement, theshutdown_service()
member function will destroy all copies of user-defined handler objects that are held by the service. - Uninvoked handler objects scheduled for deferred invocation are destroyed for the
io_service
and any of its strands.
Consider either:
- Controlling the lifespan of the
io_service
object. One approach can be found in this answer. - Running the
io_service
to completion. This often requires setting state, cancelling outstanding operations, and preventing completion handlers from posting additional work into theio_service
. Boost.Asio provides an official timeout example, and a timeout approach with running to theio_service
to completion is also shown here.
来源:https://stackoverflow.com/questions/18553886/clear-boostasioio-service-after-stop