程序在boost asio中用C ++ 11异步读取异步 [英] Program to read asynchronously in boost asio with C++11 future

查看:228
本文介绍了程序在boost asio中用C ++ 11异步读取异步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目的最近开发中,我使用 std :: future async_read_some 用户线程,可以在异步I / O上等待特定持续时间,并显示为同步过程。但是调用获取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(); / *在对等体断开的情况下不会返回* /
} catch(std :: system_error& error){
/ *只在错误被捕获时打印* /
}
断裂;
case std :: future_status :: timeout:
...
case std :: future_status :: deferred:
...
};

当程序根据情况运行时,进程汇 - 它看起来完全像是死锁asio实现。在执行 std :: future :: get()

  ///等待状态准备好并重新抛出任何存储的异常
__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); < - //可用源的最深跟踪
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()



linux 3.8.0-37-generic#53〜precise1-Ubuntu SMP Wed Feb 19 21:39:14 UTC 2014 i686 i686 i386 GNU / Linux

io_service.run()的线程中是否正在执行此操作?
如果是,那么 std :: future_status status = result.wait_for(std :: chrono :: millisecond(1000)); 将阻止,因为不能接收结果直到io_service返回到它的事件循环,以便能够检查新数据。
所以使用 future 只有当你从另一个线程(它可以阻止,而Boosts io_service可以做的工作)访问它是有意义的。



如果你想在同一个线程中做一切,你将需要以异步风格工作,例如与操作完成时调用的回调。


In the recent development of my project have I used std::future with async_read_some so that caller, say user thread, can wait for specific duration on asynchronous I/O and appear like a synchronous procedure. But call to get std::future object async_read_some function yields never returns in case that the remote connecting peer corrupts. It seems that system error in asynchronous operation is not propagated as stated at all.

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:
        ...
};

when program runs in according scenario, the process "sinks" - it appears exactly like there is deadlock in asio implementation. A trace stops in implementation of 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);
  }

After investigating into documentation, I found very few words

std::future<std::size_t> my_future = my_socket.async_read_some(my_buffer, boost::asio::use_future); The initiating function (async_read_some in the above example) returns a future that will receive the result of the operation. If the operation completes with an error_code indicating failure, it is converted into a system_error and passed back to the caller via the future.

However, there is NOTHING my program catches around 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

解决方案

Are you doing that in the thread that performs io_service.run()? If yes then std::future_status status=result.wait_for(std::chrono::millisecond(1000)); will block because no result can be received until the io_service returns to it's event loop to be able to check for new data there. So using the future would only make sense if you access it from another thread (which can block while Boosts io_service can do the work).

If you want to do everything in the same thread you will be required to work in an asynchronous style, e.g. with the callbacks that are invoked when the operation completes.

这篇关于程序在boost asio中用C ++ 11异步读取异步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆