boost :: asio :: io_service :: run在没有工作时不返回

时间:2015-06-06 14:51:28

标签: c++ c++11 boost boost-asio

来自Asio文档

  

run()函数会阻塞,直到所有工作完成,并且不再有调度程序,或者直到io_service停止。

在下面的代码片段中,除了调试输出(即时计算)之外,Asio没有工作,但是run()没有返回。

#define BOOST_ASIO_ENABLE_HANDLER_TRACKING

#include <iostream>
#include <thread>

#include <boost/asio.hpp>

int main()
{
  namespace asio = boost::asio;

  asio::io_service ios;

  asio::ip::udp::endpoint ep(boost::asio::ip::udp::v4(), 9876);
  auto socket = new asio::ip::udp::socket(ios, ep);
  std::thread th([&]
  {
      ios.dispatch([]{ std::cout << "before run()" << std::endl;});
      ios.run();
      std::cout << "after run()" << std::endl;
  });

  std::this_thread::sleep_for(std::chrono::seconds(5)); // wait for io_service to launch

  socket->cancel();
  socket->close();
  delete socket; // just in case

  std::cout << "socket is closed" << std::endl;

  th.join(); // hangs here

  std::cout << "exiting..." << std::endl;
}

挂起前的输出是

@asio|1433598048.101578|0*1|io_service@0x611000009f00.dispatch
@asio|1433598048.101785|>0|
before run()
socket is closed

没有套接字,这个代码段工作正常。

我使用的是Ubuntu 15.04,我尝试了gcc-4.9.2,gcc-5.1,clang-3.6,boost-1.56和boost-1.58。

这是一个错误,如果有的话,是否有任何解决方法,或者我只是误解了什么?

更新
此错误仅使用以下文件进行复制,必须与其他翻译单元中的上述代码段一起编译:

#include <boost/asio.hpp>

namespace asio = boost::asio;

class my_server
{
public:
  my_server(asio::io_service& ios);

private:

  asio::io_service& _ios;
  asio::ip::udp::socket _socket;
};

my_server::my_server(boost::asio::io_service &ios)
  : _ios(ios), _socket(ios, asio::ip::udp::endpoint())
{
}

我在https://github.com/shadeware/asio-problem

创建了最小项目

1 个答案:

答案 0 :(得分:1)

显然,如果您选择定义BOOST_ASIO_ENABLE_HANDLER_TRACKING,则必须在所有boost::asio个翻译单元中执行此操作。我没有在文档中看到这一点,但我确实在Boost mailing list上找到了它。

当我添加

add_definitions(-DBOOST_ASIO_ENABLE_HANDLER_TRACKING)

CMakeLists.txt,以便全局应用,然后我就不会看到挂起。