2016-02-29 70 views
1

正在瀏覽asio功能use_future,閱讀source codeasio :: use_future和事件循環

但無法弄清楚它是如何工作的。說,如果我打電話

auto fut = async_write(sock, buffer, use_future) 

fut變得std::future(根據源代碼)。現在,如果我打電話fut.get()我應該能夠等待異步操作完成並獲得返回值。在use_future.hpp文件中,我看到asio async_result處理程序分辨率等標準。

但是,如果我阻止future::get()調用,IO循環如何繼續工作,以便操作可以完成?它是否創建一個系統線程?

回答

3

的短耳tutorial提到,對於單線程應用程序,可以觀察反應很差,如果處理程序需要很長時間才能完成。在這種情況下,如果只有一個線程正在處理io_service,那麼會發現死鎖。

當使用boost::asio::use_future,發起動作:

  • 發起底層操作用,將設置在std::promise
  • 返回到與相關聯的主叫方一個std::future的值或誤差完成處理程序std::promise

如果一個線程處理I/O服務,它阻止在future::get(),然後完成處理程序將設置std::promise將永遠不會被調用。防止這種情況發生是應用程序的責任。 official futures example通過創建一個專用於處理I/O服務的附加線程並在不處理I/O服務的線程內等待std::future來實現此目的。

// We run the io_service off in its own thread so that it operates 
// completely asynchronously with respect to the rest of the program. 
boost::asio::io_service io_service; 
boost::asio::io_service::work work(io_service); 
std::thread thread([&io_service](){ io_service.run(); }); 

std::future<std::size_t> send_length = 
    socket.async_send_to(..., boost::asio::use_future); 

// Do other things here while the send completes. 

send_length.get(); // Blocks until the send is complete. Throws any errors. 
+0

這更有意義。但是如果在處理程序中使用'use_future',那麼'io_service :: run'調用了什麼呢?這將再次陷入僵局。看起來這個功能並不像我看起來那麼安全=( – PSIAlt

+1

@PSIAlt)在處理程序中無限期阻塞的調用函數很少安全。當我使用'use_future'時,我只在沒有處理I/O服務的線程中使用它,並且這些線程啓動的所有異步操作都使用'use_future'。這種方法沒有用戶處理程序,可以在其中調用阻塞調用 –

+0

,但這也意味着您應該使用每個連接的線程來使此模式有效。我會更好地堅持yield_context,它似乎更容易擴展。 – PSIAlt

1

它是否創建系統線程?

號你 應該 免費哪個線程(S)上決定運行io_service::run

+1

的[特定平臺實現說明](http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/overview/implementation.html)列出了所有內螺紋。這個[demo](http://coliru.stacked-crooked.com/a/d85347255e8d84dd)表明即使操作系統操作完成,如果'io_service'沒有得到處理,那麼promise也不會被滿足。 –

+0

所以問題是:如果我在'future :: get'調用中只有1個線程和它的阻塞,其中'io_service :: run'被處理以便調用'promise_handler'? – PSIAlt