2011-05-20 188 views
10

在調用運行一些指令的boost :: thread之後,是否有可能返回主線程?C++ boost ::線程在主線程上執行代碼?

我的代碼基於proactor模式,但某個函數可能需要一些時間,所以爲了不阻塞整個程序,我創建了一個運行此函數的線程。 當這個函數結束時,我需要調用另一個函數,但它必須在主線程上運行。 我有一個連接池,這不是線程安全的,我真的想避免互斥。

是否有穩定的方式來運行主線程上的函數(調用另一個線程)?

就像在的ObjectiveC performSelectorOnMaintThread

+0

你正在尋找一個消息隊列。 – 2011-05-20 11:48:09

+0

當然,如果你睡在主線程上,你會阻塞主線程。你還會期待什麼?睡覺不能像廣告一樣工作? – 2011-05-20 11:58:33

+0

(另外,抱歉,我的意思是[消息泵(http://en.wikipedia.org/wiki/Event_loop))。 – 2011-05-20 11:59:56

回答

2

我想你可能想看看boost asio strands。他們會讓你指定哪個線程(線程)做一些炒鍋,它會自動排隊。

請注意,一根線實際上更像是一根纖維(意思是說,如果有比實際線更多的線,那麼線將被複用到可用線上)。

IIRC此不會但是給你機會明確指定主線程1。然而,這通常不是實際的要求:什麼股讓你容易做的是確保在一個股中的操作運行在相同的邏輯線程上,即在並行內沒有併發是永遠不可能的

瑣事:升壓短耳io_service.run()是泵

下面是升壓短耳樣品頁面的消息的示例:http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/examples.html

+0

股很有希望。但是,如果我理解正確的話,我應該讓我的連接池的Runnable,並使其等待,直到它被徵求(例如獲取連接),我應該怎樣讓它等待,與互斥體cond_wait? – TheSquad 2011-05-20 12:45:40

+0

我對連接池一無所知。添加到Boost Asio Samples的鏈接 – sehe 2011-05-20 12:56:20

0

在多線程應用程序(至少對於我)主線程沒有太多的工作,一切都抵消了在啓動時創建的其他線程。主線程只會阻止/等待(條件變量),直到指示我們很好退出。所有工作都在線程之間翻轉/翻轉,這使事情變得更容易。

而且如上所示,最好的方法是擁有消息隊列(每個隊列包裝一個工作線程或池),並且可以將消息發佈到另一個或另一個消息隊列中。使用回調函數和其他消息機制,可以讓「主」線程向工作線程發送消息來完成工作,並提供回調以在完成結果時將消息發送回「主」線程。在此期間,如果有其他工作要做,「主」線程可以在等待結果的同時繼續處理其他消息和操作。

5

如果你想要一個函數在主線程中運行,你將不得不實現某種類型的消息傳遞系統。因此,例如,您將啓動您的主線程,然後啓動工作線程。工作線程可以完成工作,而主線程將等待工作線程的返回值(即主線程將檢查消息隊列或其他特性)。當工作線程完成時,它將通過指向它想讓主線程運行的函數的指針傳遞給主線程的消息隊列的結構(即消息)。您的郵件可以很簡單:

struct message 
{ 
    typedef void (*func_ptr)(void); //or whatever your function signature would be 

    func_ptr function; 
    bool finished; 

    message(): function(NULL), finished(false) {} 
}; 

因此,當工作線程完成後,它會創建一個新的消息,初始化消息中的函數指針,並推動該消息返回到隊列,主線程是等待。主線程然後從隊列中讀取消息,並調用該函數。

順便說一句,使主線程「等待」而不必將其保留在循環中並消耗CPU週期的有效方法是在主線程和工作者之間使用信號量或條件變量(如boost::condition) 。

與一個或多個音符......一個「消息隊列」是一個簡單的std::queue<message>用適當的鎖定訪問主線程讀取,並輔助線程寫入。對於主線程寫入的工作線程,也可以有另一個消息隊列,如果需要線程之間的雙向通信,則工作線程將讀取。

0

如果您在Visual Studio 2010中運行,它應該在的調試工作始終。但是,由於可能需要禁用,然後重新啓用「優化」才能使發佈工作。

0

我也有類似的情況。帶升壓線程的mfc對話框。解決我添加signals2到boost線程並將它們綁定到對話框上的成員函數。當信號進入對話成員函數時,我檢查了線程ID。如果線程ID不同於對話線程ID,我會將一個boost函數推送到函數的std :: queue(相同簽名)上。 onidle,kickidle我檢查隊列並執行這些功能。

相關問題