使用C ++ 11将来在boost asio中异步读取的程序

时间:2014-03-25 06:55:08

标签: c++11 boost-asio

在我项目的最近开发中,我使用了std::futureasync_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

1 个答案:

答案 0 :(得分:0)

您是否在执行io_service.run()的主题中执行此操作? 如果是,则std::future_status status=result.wait_for(std::chrono::millisecond(1000));将阻止,因为在io_service返回其事件循环之前不能接收任何结果,以便能够在那里检查新数据。 所以使用future只有从另一个线程访问它时才有意义(当Boosts io_service能够完成工作时可以阻塞它。)

如果您想在同一个线程中执行所有操作,则需要以异步方式工作,例如使用操作完成时调用的回调。