2012-11-21 92 views
0

我想用超時實現async_connect()。async_connect()超時與多個線程執行io_service.run()

async_connect_with_timeout(socket_type & s, 
     std::function<void(BoostAndCustomError const & error)> const & connect_handler, 
     time_type timeout); 

當操作完成connect_handler(error)調用與error指示操作結果(包括超時)。

我希望能使用timeouts example 1.51的代碼。最大的區別是我使用多個工作線程執行io_service.run()。

需要進行哪些更改才能使示例代碼正常工作?

我的問題是:

  1. 當調用:

    Start() { 
        socket_.async_connect(Handleconnect); 
        dealine_.async_wait(HandleTimeout); 
    } 
    

    HandleConnect()可以在另一個線程完成之前就async_wait()(不可能的,但有可能)。我是否需要strand包裝Start(),HandleConnect()HandleTimeout()

  2. 如果HandleConnect()首次調用沒有錯誤,但deadline_timer.cancel()deadline_timer.expires_from_now()失敗,因爲HandleTimeout()「已排隊等待調用在不久的將來」?看起來像示例代碼讓HandleTimeout()關閉套接字。這種行爲(連接之後我們開始一些操作後愉快地開始連接後,計時器關閉連接)很容易導致嚴重的頭痛。

  3. 如果HandleTimeout()socket.close()先被調用,該怎麼辦? HandlerConnect()有沒有可能已經「排隊」而沒有錯誤?文檔說:「任何異步發送,接收或連接操作都將立即取消,並且會在出現boost::asio::error::operation_aborted錯誤時結束。」多線程環境中的「立即」意味着什麼?

+0

預計什麼樣的線程'Start()'函數運行?它是「io_service」線程還是其他「用戶」線程之一? –

+0

@IgorR。我正在使用[HTTP Server 3示例](http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/examples.html)中的線程池。更確切地說:我的「用戶」線程使用io_service.post()。 – Daszek

+0

@IgorR。 'Start()'將從'io_service'線程調用'io_service.run()'被調用。 – Daszek

回答

1
  1. 你應該鏈包裹每個處理程序,如果你想避免在不同的線程的並行執行。我想一些完成處理程序將訪問socket_或計時器,所以你一定要包裝Start()以及一個鏈。但是,使用io_service-per-CPU模型會不會更簡單,即將您的應用程序基於io_service池?恕我直言,你會得到很多少頭痛。

  2. 是的,這是可能的。爲什麼這是頭痛?套接字由於「假超時」而關閉,並且您開始重新連接(或其他)過程,就像由於網絡故障而關閉一樣。

  3. 是的,它也是可能的,但是它也不應該爲正確設計的程序造成任何問題:如果在HandleConnect中嘗試在封閉套接字上發出一些操作,則會得到相應的錯誤。無論如何,當您嘗試發送/接收數據時,您並不知道當前套接字/網絡狀態。

+0

1)'async_connect_with_timeout()'會在少數應用程序中使用。我不能將它們限制爲一種特定的線程模型。 2)我不同意。當我調用'connect_handler()'沒有錯誤時,不會有「false timeout」關閉它。想象一下,如果我的函數是'boost :: asio :: async_connect()'。調用'connect_handler()'意味着操作**完成**。 3)你在這裏沒有回答我的問題。我想要的事實不是像「正確設計」這樣的口號。主要問題是:「提升示例還行嗎?」。 – Daszek

+0

@Daszek 2)如果你使用asio :: strand沒有這樣的問題。 3)*在多線程環境中,「立即」意味着什麼?* - 不是多線程,而是在異步環境中。這意味着當你調用'cancel()'(未排隊等待執行)時,將從當前處理程序調用回調函數。 – PSIAlt

+0

@PSIAlt 3)我說**多線程**因爲多線程調用io_service.run()。請堅持'close()'。我不想處理'cancel()'。另外你所說的似乎與IgorR的說法相矛盾。 – Daszek