2014-03-25 66 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

我正在檢查未來的另一個線程,輪詢時間輪循模式。所以對我而言,未來肯定是最容易使用的。就像我說的,如果有人能夠告訴我該如何處理未來遠程對象腐敗時的錯誤,這將會很有幫助。 –