2014-03-25 65 views
2

在我的项目的最近的发展中,我用std::futureasync_read_some,使调用者,说用户线程,可以等待异步I/O的特定持续时间,并出现像一个同步程序。但是调用获取std :: future对象async_read_some函数在远程连接对等点损坏的情况下不会返回。看起来,异步操作中的系统错误根本没有传播。程序读取异步升压asio与C + + 11未来

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在上面的例子中)返回一个未来将接收操作结果。如果操作完成且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

“看起来异步操作中的系统错误没有像所述的那样传播。” 内部asio使用std :: promise来创建返回的将来。阿西奥不会介绍一些神奇的未来的东西。这个未来必须处于就绪状态才能到达你的try/catch块,这意味着异常是由asio设置的,或者值是由asio设置的。所以错误不能在那里。 再次检查你对这个未来物体的使用情况,可能你正在做一些错误的操作。 – inkooboo

+0

@inkooboo对不起,这个故事对你来说可能显得模糊不清,但实际上,它只在远程对等损坏之前返回正常。如果有人能够解释我asio如何转换system_error并通过未来传回给调用者,这将会有所帮助。 –

+1

您可以查看源代码“boost/asio/impl/use_future.hpp”以获取更多想法。 当您将'boost :: asio :: use_future'作为'async_read_some'的完成处理程序传递时,asio将'promise_handler'的对象创建为完成处理程序。返回的将来是根据它的承诺创建的(请参阅async_result类模板特化)。 你可以尝试在这个文件中设置一些断点,然后尝试调试。可能会有所帮助。 – inkooboo

回答

0

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

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

+0

我正在检查未来的另一个线程,轮询时间轮循模式。所以对我而言,未来肯定是最容易使用的。就像我说的,如果有人能够告诉我该如何处理未来远程对象腐败时的错误,这将会很有帮助。 –