C++ Boost asio - 停止 io_service
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4808848/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Boost asio - stopping io_service
提问by Mark Nelson
I'm using boost::asio to do some very basic UDP packet collection. The io_service object is instantiated in a worker thread, and io_service.run() is called from inside that thread. My problem is getting io_service.run() to return when I am done collecting packets.
我正在使用 boost::asio 来做一些非常基本的 UDP 数据包收集。io_service 对象在工作线程中实例化,并且从该线程内部调用 io_service.run()。我的问题是在我完成收集数据包后让 io_service.run() 返回。
I'm not clear on what methods of io_service can be called from other threads when it comes time to stop my worker thread. I have a reference to the io_service object, and from a different thread I make this call:
我不清楚在停止我的工作线程时可以从其他线程调用 io_service 的哪些方法。我有一个对 io_service 对象的引用,我从一个不同的线程调用:
ios.dispatch( boost::bind( &udp_server::handle_kill, this ) );
In my udp_server class, the handler for that function cancels the pending work from a single boost::asio::ip::udp::socket and a single boost::asio::deadline_timer object. Both have pending async work to do. At that point I call ios.stop():
在我的 udp_server 类中,该函数的处理程序从单个 boost::asio::ip::udp::socket 和单个 boost::asio::deadline_timer 对象取消挂起的工作。两者都有待处理的异步工作要做。那时我打电话给 ios.stop():
void udp_server::handle_kill()
{
m_socket.cancel();
m_timer.cancel();
m_ios.stop();
}
With no work pending, I expect at this point that my call to ios.run() should return - but this does not happen.
由于没有待处理的工作,我希望此时我对 ios.run() 的调用应该返回 - 但这不会发生。
So why does it not return? The most likely explanation to me is that I shouldn't be calling io_service::dispatch() from another thread. But the dispatch() method kind of seems like it was built to do just that - dispatch a function call in the thread that io_service::run() is working in. And it seems to do just that.
那么它为什么不返回呢?对我来说最可能的解释是我不应该从另一个线程调用 io_service::dispatch() 。但是 dispatch() 方法似乎就是为了做到这一点而构建的 - 在 io_service::run() 正在工作的线程中调度函数调用。它似乎就是这样做的。
So this leaves me with a few related questions:
所以这给我留下了一些相关的问题:
- Am I using io_service::dispatch() correctly?
- If all tasks are canceled, is there any reason that io_service::run() should not return?
- socket::upd::cancel() doesn't seem to be the right way to close a socket and abort all work. What is the right way?
- 我是否正确使用 io_service::dispatch() ?
- 如果所有任务都被取消,io_service::run() 是否有理由不返回?
- socket::upd::cancel() 似乎不是关闭套接字并中止所有工作的正确方法。什么是正确的方法?
asio is behaving pretty well for me, but I need to get a better understanding of this bit of architecture.
asio 对我来说表现得很好,但我需要更好地理解这一点架构。
More data
更多数据
socket::udp::cancel() is apparently an unsupported operation on an open socket under Win32 - so this operation fails by throwing an exception - which does in fact cause an exit from io_service::run(), but definitely not the desired exit.
socket::udp::cancel() 显然是 Win32 下打开的套接字上不受支持的操作 - 因此该操作因抛出异常而失败 - 这实际上会导致从 io_service::run() 退出,但绝对不是所需的出口。
socket::udp::close() doesn't seem to cancel the pending async_receive_from() task, so calling it instead of socket::udp::cancel() seems to leave the thread somewhere inside io_service::run().
socket::udp::close() 似乎没有取消挂起的 async_receive_from() 任务,所以调用它而不是 socket::udp::cancel() 似乎将线程留在 io_service::run() 内的某个地方。
回答by Sam Miller
Invoking io_service::stop
from another thread is safe, this is well describedin the documentation
io_service::stop
从另一个线程调用是安全的,这在文档中有很好的描述
Thread Safety
Distinct objects: Safe.
Shared objects: Safe, with the exception that calling reset() while there are unfinished run(), run_one(), poll() or poll_one() calls results in undefined behaviour.
线程安全
不同的对象:安全。
共享对象:安全,除了在有未完成的 run()、run_one()、poll() 或 poll_one() 调用时调用 reset() 会导致未定义的行为。
as the comments to your question indicate, you really need to boil this down to a reproducible example.
正如对您的问题的评论所表明的那样,您确实需要将其归结为一个可重现的示例。