来自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())
{
}
创建了最小项目
答案 0 :(得分:1)
显然,如果您选择定义BOOST_ASIO_ENABLE_HANDLER_TRACKING
,则必须在所有boost::asio
个翻译单元中执行此操作。我没有在文档中看到这一点,但我确实在Boost mailing list上找到了它。
当我添加
add_definitions(-DBOOST_ASIO_ENABLE_HANDLER_TRACKING)
到CMakeLists.txt
,以便全局应用,然后我就不会看到挂起。