在我项目的最近开发中,我使用了std::future
和async_read_some
,因此调用者(比如用户线程)可以在异步I / O上等待特定的持续时间,并且看起来像一个同步过程。但是调用get std :: future对象async_read_some函数会在远程连接对等体损坏时永远不会返回。似乎异步操作中的系统错误根本没有传播。
std::future<size_t> result=socket.async_read_some(boost::asio::buffer(data, size), boost::asio::use_future);
std::future_status status=result.wait_for(std::chrono::millisecond(1000));
switch(status){
case std::future_status::ready:
try{
bytes=result.get(); /* never returns in case of peer disconnection */
}catch(std::system_error & error){
/* print something only if error is caught */
}
break;
case std::future_status::timeout:
...
case std::future_status::deferred:
...
};
当程序在相应的场景中运行时,进程“下沉” - 它看起来就像asio实现中存在死锁一样。跟踪在std::future::get()
/// Wait for the state to be ready and rethrow any stored exception
__result_type
_M_get_result() const
{
_State_base::_S_check(_M_state);
_Result_base& __res = _M_state->wait();
if (!(__res._M_error == 0))
--> rethrow_exception(__res._M_error); <-- //deepest trace with available source
return static_cast<__result_type>(__res);
}
在调查文档后,我发现很少的单词
std::future<std::size_t> my_future = my_socket.async_read_some(my_buffer, boost::asio::use_future);
启动函数(上例中的async_read_some)返回将接收操作结果的future。如果操作以error_code指示失败完成,则会将其转换为system_error并在将来传递给调用者。
但是,我的程序没有发现result.get()
。
PS: linux 3.8.0-37-generic #53~precise1-Ubuntu SMP Wed Feb 19 21:39:14 UTC 2014 i686 i686 i386 GNU/Linux
答案 0 :(得分:0)
您是否在执行io_service.run()
的主题中执行此操作?
如果是,则std::future_status status=result.wait_for(std::chrono::millisecond(1000));
将阻止,因为在io_service返回其事件循环之前不能接收任何结果,以便能够在那里检查新数据。
所以使用future
只有从另一个线程访问它时才有意义(当Boosts io_service能够完成工作时可以阻塞它。)
如果您想在同一个线程中执行所有操作,则需要以异步方式工作,例如使用操作完成时调用的回调。