2011-10-02 124 views
0

雖然我在Borland C++應用程序的背景下引用了它,但是這個問題既是Borland特有的,也是通用的。在一個Borland C++項目中,我觀察到用戶與GUI的交互(比如菜單項點擊)的優先級低於使用Synchronize()委託給主線程的任務,儘管用戶交互正在發生幾毫秒前。當主線程可用時,首先完成委託任務,然後執行與用戶交互對應的操作。工作者線程將任務委託給主線程,並使用Synchronize()等待任務完成。所以我們可以將Synchronize()等同於SendMessage()。線程消息之間的優先級?

我認爲用戶交互作爲消息隊列中的消息排隊,同樣應該是委派任務的情況。但是,該任務如何首先執行?消息之間是否有優先權?

+0

這對於Borland的實現非常具體。但是,消息循環首先分派來自同步隊列的任何請求,然後繼續清空消息隊列是很常見的。 –

+0

@Hans感謝您的回覆。我對文本進行了一些修改 - 「主線程可用時」。不知道這是否重要,以防萬一。 –

回答

1

直到幷包括C++ Builder 5,Synchronize()確實打電話給SendMessage()。但在C++ Builder 6中,Synchronize()被重寫爲不再使用SendMessage()(以支持CLX下的Linux)。現在將請求放入FIFO隊列中,VCL定期調用CheckSynchronize()來處理隊列。即使CLX早已死亡,Synchronize()仍然使用相同的FIFO隊列(並且多年來它已經得到增強)。

除此之外,在使用SendMessage()的情況下,它具有更高的優先級。用戶交互將消息發佈到主線程消息隊列(又名PostMessage())。雖然SendMessage()直接轉到窗口的wndproc,但直到接收窗口的擁有線程執行消息處理(如果由不同的線程發送)(Synchronize()曾經是這種情況),它纔會被調用。待處理SendMessage()對主線程消息隊列的請求具有比掛起的已發送消息更高的優先級,因爲在處理待處理的SendMessage()請求之前,還有其他線程/進程被阻塞。

+0

Lebeau。謝謝回覆。我認爲Synchronize()的FIFO與GUI線程的消息隊列不同,前者比後者更優先。 GUI線程也會在空閒時執行消息處理。那是對的嗎? –

+0

從BCB6開始,FIFO隊列與消息隊列是分開的,是的。由於'Synchronize()'不再使用消息隊列進行同步,現在它實際上具有較低的優先級。主線程在空閒時以及收到「WM_NULL」消息時調用「CheckSynchronize()」。 'Synchronize()'向主消息隊列發佈'WM_NULL'消息來喚醒主線程,讓它知道'CheckSynchronize()'需要很快被調用。這與舊的'SendMessage()'邏輯非常不同(但更具可移植性)。 –

+0

感謝您的回覆。我現在有點困惑。 Synchronize()現在依賴於發送到消息隊列的WM_NULL消息,並且用戶交互也會發布到此消息隊列中。 Synchronize()如何在運行Borland版本6的項目中看到更高的優先級? –