Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Boost asio-停止io_服务_C++_Boost_Boost Asio - Fatal编程技术网

C++ Boost asio-停止io_服务

C++ Boost asio-停止io_服务,c++,boost,boost-asio,C++,Boost,Boost Asio,我正在使用boost::asio进行一些非常基本的UDP数据包收集。io_服务对象在工作线程中实例化,并从该线程内部调用io_服务.run()。我的问题是在收集完数据包后让io_service.run()返回 我不清楚在停止我的工作线程时,可以从其他线程调用io_服务的哪些方法。我有一个对io_服务对象的引用,我从另一个线程调用: ios.dispatch( boost::bind( &udp_server::handle_kill, this ) ); 在我的udp_服务器类中,该函

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

我不清楚在停止我的工作线程时,可以从其他线程调用io_服务的哪些方法。我有一个对io_服务对象的引用,我从另一个线程调用:

ios.dispatch( boost::bind( &udp_server::handle_kill, this ) );
在我的udp_服务器类中,该函数的处理程序从单个boost::asio::ip::udp::socket和单个boost::asio::deadline_计时器对象中取消挂起的工作。两者都有挂起的异步工作要做。此时我调用ios.stop():

在没有挂起的工作的情况下,我希望此时可以返回对ios.run()的调用,但这不会发生

那么为什么它不回来呢?最可能的解释是,我不应该从另一个线程调用io_service::dispatch()。但是dispatch()方法似乎就是为了实现这一点而构建的——在io_service::run()工作的线程中调度函数调用。它似乎就是这样做的

这就给我留下了几个相关的问题:

  • 我是否正确使用io_服务::dispatch()
  • 如果所有任务都已取消,是否有任何原因导致io_service::run()不返回
  • 套接字::upd::cancel()似乎不是关闭套接字并中止所有工作的正确方法。正确的方法是什么
  • asio对我来说表现得很好,但我需要更好地理解这一点架构

    更多数据 套接字::udp::cancel()显然是Win32下打开的套接字上不受支持的操作-因此此操作因引发异常而失败-这实际上会导致io_service::run()退出,但肯定不是所需的退出


    socket::udp::close()似乎不会取消挂起的async_receive_from()任务,因此调用它而不是socket::udp::cancel()似乎会将线程留在io_service::run()中的某个位置。

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

    线程安全 不同对象:安全

    共享对象:安全,具有 调用reset()时发生异常 有未完成的run(),run_one(), poll()或poll_one()调用会导致 未定义的行为


    正如对您问题的评论所指出的,您确实需要将其归结为一个可重复的示例。

    是否有理由将
    handle\u kill
    发送到
    io\u服务
    ?在该线程中调用
    handle\u kill()
    应该是安全的。如果这样做,它是否仍然挂在
    run()
    ?这是一个工作线程-除了读取数据包之外,它什么都不做。终止线程的动力来自另一个线程中的GUI。无论我使用哪种方法,都必须有一种线程安全的方式来与io_service::run()线程通信。在我看来,io_service::dispatch()就是为了满足这种需要而构建的。handle_kill()似乎是在正确的线程中调用的。您应该能够从任何线程停止
    io_服务
    ,而不管它是否是该特定
    io_服务
    的工作线程。另外,
    dispatch()
    post()
    是相同的,不同的是如果可能,
    dispatch()
    可以立即内联调用函数(如果
    dispatch
    是从
    io\u服务
    线程调用的)。因此,如果您知道您的
    dispatch()
    调用永远不会在
    io\u服务
    线程上,那么它与
    post()
    相同。但这并不能解决你的问题。你能给出一个10-15行的代码样本来重现这个问题吗?我正在准备一个简短的例子来说明这一点。同时,我发现从另一个线程调用ios::stop()实际上会导致ios:run()以我想要的方式退出。我曾经(现在仍然)不愿意对一个没有显式调用线程安全行为保证的方法进行这样的调用,但它似乎确实有效。为什么我通过dispatch()进行的间接调用不起作用的问题还有待复制和理解。@MarkNelson,请接受提供的答案,如果它足够的话。我阅读了关于线程安全的说明,我不得不承认我对文档中“共享对象”的含义有点一无所知。这似乎相当笼统,但回想起来,我认为你是对的,它描述得很好。这些知识并没有具体回答我的问题,但因为它为解决我的bug扫清了道路,所以它是次好的选择。谢谢@马克:如果你满意的话,欢迎接受我对你问题的回答。您可能想为您的bug发布一个新问题。
    void udp_server::handle_kill()
    {
        m_socket.cancel();
        m_timer.cancel();
        m_ios.stop();
    }