2011-01-19 149 views
9

這與this question有些相關,但我認爲我需要多瞭解一點。我一直在試着讓我的頭腦幾天(在其他部分工作的同時)如何做到這一點,但現在是時候讓我咬緊牙關並獲得多線程。而且,我比有關問題的信息多一點。boost :: asio,線程和同步

首先,關於多線程。由於我一直在測試我的代碼,所以我沒有爲任何多線程所困擾。它只是一個控制檯應用程序,它啓動與測試服務器的連接,然後處理所有其他事情。主循環是這樣的:

while(true) 
{ 
    Root::instance().performIO(); // calls io_service::runOne(); 
} 

當我寫我的主要應用,我猜這個解決方案是不能接受的(因爲它會在消息循環中被調用哪個,雖然可能會有當消息隊列阻塞等待消息時,你可以改變它,這樣消息循環就不會阻塞,但是這不會阻止CPU使用率通過屋頂?)

解決方案它似乎是要拋出另一個線索。好的。但是當我沒有工作要做時,我已經讀了io_service::run()。那是什麼?那是什麼時候沒有數據,或沒有連接?如果至少有一個連接存在,它會保持活着嗎?如果是這樣,這不是什麼大問題,因爲我只需要在第一次連接時創建一個新線程,並且我很高興如果一切都停止時就停止了。我想我對'沒有工作要做'的定義感到困惑。

然後我不得不擔心同步我的提升線程與我的主要GUI線程。所以,我想我的問題是:

  1. 在客戶端應用程序中使用boost :: asio關於線程並保持它們活着的最佳實踐方式是什麼?
  2. 當從主線程寫入套接字到IO線程時,是否使用boost::asio::post實現同步,以便稍後在io_service中發生該調用?
  3. 當收到數據時,人們如何將數據返回到UI線程?在過去,當我使用完成端口時,我做了一個特殊的事件,可以使用:: SendMessage將數據發送回主UI線程。這不是優雅,但它的工作。

今天我會再讀一些,但如果能夠從已經完成這項工作的人那裏得到正面評價,那將是一件好事。 Boost :: asio文檔並不是很好,迄今爲止我的大部分工作都是基於一些文檔,一些試驗/錯誤以及網絡上的一些示例代碼。

回答

6

1)看看io_service::work。只要工作對象存在,io_service :: run就不會返回。因此,如果您開始清理工作,請銷燬工作對象,取消所有未完成的操作,例如套接字上的async_read,等待運行返回並清理資源。

2)io_service :: post將異步執行來自運行io_service的線程的給定處理程序。可以使用回調來獲取執行操作的結果。

3)您需要某種形式的消息傳遞系統來通知您的GUI線程新數據。這裏有幾種可能性。

就你對文檔的評論而言,我的Asio是一個更好記錄的boost庫,它附帶清晰的例子。

+0

+1 io_service :: work是我自己解決這個問題的方法。 – 2011-01-19 13:31:59

+0

感謝您的回覆。當你說有幾種可能性時,過去你曾使用過什麼? – 2011-01-19 14:11:11

1

boost::io_service::run()只有在沒有任何操作時纔會返回,因此沒有異步操作正在等待,例如,異步接受/連接,異步讀/寫或異步定時器等待。所以在致電io_service::run()之前,您首先必須啓動任何異步操作。

我還沒有你有控制檯或GUI應用程序?在任何情況下,多線程看起來都是過度的。您可以將Asio與消息循環一起使用。如果是win32 GUI,則可以從您的OnIdle()處理程序調用io_service :: run_one()。在控制檯應用程序的情況下,您可以設置deadline_timer定期檢查(每200毫秒?)用戶輸入,並與io_service::run()一起使用。一切都在單線程來大大簡化解決方案

2

1)什麼是客戶端應用程序使用 提升 :: ASIO關於線程和保持 他們活着的最佳實踐方法是什麼?

隨着documentation suggests,線程調用io_service::run池是最具可擴展性和最容易實現。

2)當從主 線程寫入插座的IO線程,使用 的boost ::支持ASIO ::後 同步實現的,因此呼叫 在io_service對象後會發生什麼?

您將需要使用a strand來保護可由多個線程調用的任何處理程序。見this answer,因爲它可以幫助你,以及這個例子。

3)當收到數據時,人們如何將數據返回到UI線程?在 過去,當我使用完成端口, 我做了一個特殊的事件,可以發回 數據回到主UI線程 使用:: SendMessage。這不是 優雅,但它的工作。

怎麼樣,當你發佈一個異步事件的io_serviceboost::function的形式提供的回調?然後事件的處理程序可以調用回調並用結果更新UI。

0

當收到數據後,人們如何將數據返回到UI線程?在過去,當我使用完成端口時,我做了一個特殊的事件,可以使用:: SendMessage將數據發送回主UI線程。這不是優雅,但它的工作

:: PostMessage可能更合適。

除非一切都在一個線程中運行,否則這些機制必須用於安全地將事件發佈到UI線程。