boost::asio::io_service::run 不 return 没有工作

boost::asio::io_service::run does not return while having no work

来自 Asio 文档

The run() function blocks until all work has finished and there are no more handlers to be dispatched, or until the io_service has been stopped.

在下面的代码片段中,Asio 除了调试输出(立即计算)外没有任何工作,但是 运行() 没有 return。

#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

创建了最小的项目

显然,如果您选择定义 BOOST_ASIO_ENABLE_HANDLER_TRACKING,那么您必须在所有 boost::asio 翻译单元中都这样做。我没有在文档中看到这个,但我确实在 Boost mailing list.

上找到了它

当我添加

add_definitions(-DBOOST_ASIO_ENABLE_HANDLER_TRACKING)

到你的 CMakeLists.txt 所以它是全局应用的然后我没有看到挂起。