提升asio - 停止io_service

时间:2011-01-26 19:13:11

标签: c++ boost boost-asio

我正在使用boost :: asio来做一些非常基本的UDP数据包收集。 io_service对象在工作线程中实例化,并且从该线程内部调用io_service.run()。我的问题是当我收集数据包时让io_service.run()返回。

我不清楚当停止我的工作线程时,可以从其他线程调用哪些io_service方法。我有一个对io_service对象的引用,并且从另一个线程我进行了这个调用:

ios.dispatch( boost::bind( &udp_server::handle_kill, this ) );

在我的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();
}

由于没有待处理的工作,我希望此时我对ios.run()的调用应该返回 - 但这不会发生。

那为什么不回来呢?对我来说最可能的解释是我不应该从另一个线程调用io_service :: dispatch()。但是dispatch()方法看起来像是为了做到这一点 - 在io_service :: run()工作的线程中调度一个函数调用。它似乎就是这样。

所以这给我留下了一些相关的问题:

  1. 我正确使用io_service :: dispatch()吗?
  2. 如果所有任务都被取消,是否有任何理由不能返回io_service :: run()?
  3. socket :: upd :: cancel()似乎不是关闭套接字并中止所有工作的正确方法。什么是正确的方式?
  4. asio对我来说表现很好,但我需要更好地理解这一点架构。

    更多数据

    socket :: udp :: cancel()在Win32下的开放套接字上显然是一个不受支持的操作 - 所以这个操作失败了,抛出一个异常 - 这实际上导致从io_service :: run()退出,但是肯定的不是理想的退出。

    socket :: udp :: close()似乎没有取消挂起的async_receive_from()任务,所以调用它而不是socket :: udp :: cancel()似乎将线程留在io_service :: run里面的某个地方()。

1 个答案:

答案 0 :(得分:24)

从另一个线程调用io_service::stop是安全的,这是文档中的well described

  

线程安全

     

不同的对象:安全。

     

共享对象:安全,有   调用reset()的异常   还有未完成的run(),run_one(),   poll()或poll_one()调用结果   未定义的行为。

正如您对问题的评论所表明的那样,您真的需要将其归结为可重复的示例。