2009-06-09 31 views
0

這是一個相當直接的問題,我基本上是在尋找一種「最佳實踐」方法來實現我想要做的。在線程之間發送字符串數據(Win32)

我有一個Win32 GUI應用程序啓動一個工作線程來做一堆阻塞調用。我希望此線程將字符串消息發送回GUI,以便它們可以顯示給用戶。

目前我在想使用SendMessage會是一個很好的方法,使用WM_COPYDATA?這是正確的軌道?我原本有一個線程安全隊列類,它將簡單的通知消息發送回GUI線程,然後將該字符串從隊列中彈出。不過,我很快退後一步,意識到我不需要排隊;我可以直接發送字符串。

任何提示?謝謝!

編輯:爲了完整,我使用C++。

+4

您最初的基於隊列的「消息傳遞」方法既標準又優雅。它比使用SendMessage更可能更快更便攜。 – 2009-06-09 05:01:48

回答

2

WM_COPYDATA可以正常工作,但我認爲最好是簡單地定義自己的私人窗口消息。在工作線程上分配字符串,並在完成後將其釋放到GUI線程中。使用PostMessage而不是SendMessage,以便不會不必要地阻止您的工作人員。

1

WM_COPYDATA用於在進程之間發送,而不是在一個進程的線程之間發送。您當然可以將它用於線程間通信,但開銷可能更大,因爲Windows可能需要做更多工作才能將數據複製到臨時緩衝區並將其傳遞到接收應用程序。

如果您關心的是應用程序的簡單性 - 堅持更容易實現的方式。如果擔心的是性能 - 請執行配置文件並選擇更快的變體。

0

在類似情況下,我總是將字符串放在資源文件中,並使用用戶消息的參數之一來發送資源標識符。如果您需要發送動態信息,我會創建一個由UI線程分配的線程安全緩衝區,並將指向緩衝區的指針傳遞給工作線程。

2

正如其他幾個人指出,自定義窗口消息可能是最好的辦法。

要考慮的另一件事是正在使用的實際內存。通過在線程之間傳遞字符串,我猜你還要傳遞線程之間字符串的所有權。這可能會導致你應該知道,包括

  • 內存泄漏的幾個問題:如果線程A職位的消息,會發生什麼,因此贈送所有權,但該窗口被銷燬前線程B處理的消息
  • 燦內存管理器支持你的字符串安全地分配和釋放內存在不同的線程上。

第一個問題可能是最有可能影響您的應用程序的問題。我認爲這是重新考慮你的原始方法的一個很好的理由。只要隊列本身得到適當的管理,就可以消除內存泄漏,因爲隊列可以充當內存的臨時所有者。

0

很大程度上取決於您希望信息流動的方式。

共享信息的最快方式可能是使用某種形式的標記來防止競爭條件的共享變量。如果有多個字符串,你可以有一個排隊的隊列。

但是,如果您沒有數據同步的經驗,那麼該模型可能很難得到正確。發送帶有附加數據的自定義Windows消息可能會證明是一個更簡單的(少bug)模型。

1

使用異步代理庫,Visual Studio 2010使這些場景變得更加容易。你可以看看在文檔here的演練,但這裏的一些不那麼僞代碼:

//somewhere stateful, e.g. main 
unbounded_buffer<stringtype> buff; 

//thread 1 
{ 
    //send a message asynchronously to the buffer 
    asend(&buff,stringtype("hello world"); 
} 

//thread 2 
{ 
    //get the message out of the buffer 
    //if this is a UI thread, receive is blocking so use try_receive which isn't 
    stringtype message = receive(&buff) 
} 

如果我今天的工具集,這樣做,我會使用一個線程隊列。