2012-03-06 120 views
0

我有一個GUI線程需要來自另一個線程(IO線程)的信息。 IO線程的所有工作都是從串口獲取信息。 Gui致其所有的功能就是讀取提取信息並將它們顯示在表格中。在C++中共享數據的線程

我在想也許,IO線程應該把數據放在受互斥鎖保護的全局結構中,然後GUI線程應該從該結構讀取數據。有更好的實施嗎? 在這種情況下,使用臨界區比互斥更好嗎?

現在我知道我會得到一個回覆​​,說你爲什麼不使用GUI線程來獲取IO數據,所以我不需要多線程。是的,我知道我只是想舉一個簡單的例子來學習最佳實踐:)

謝謝!

回答

1

我建議是同一個結構的兩個不同的實例。當您的IO線程準備好更新GUI線程時,它會抓取一個互斥體,將其結構複製到GUI線程的結構中,解鎖互斥體並通知GUI線程它應該讀取結構的更新副本。

至於你的關鍵部分,這只是指一段代碼只能執行一次的概念。主要是因爲你可能會得到不一致的狀態。您創建臨界區的方式是使用鎖互斥和解鎖互斥對其進行門控。

+0

嗨,每個複製都有什麼好處一個擁有自己的結構體然後共享一個全局結構體,我仍然會像你提到的那樣在任何情況下使用互斥體? 關於關鍵部分,我認爲有些東西實際上被稱爲操作系統的關鍵部分,就像一個互斥體,因爲我認爲互斥體總是名爲互斥體,因此在應用程序中共享。 – Kam 2012-03-06 11:45:49

+0

嗯如果我需要通知GUI線程何時讀取它自己的結構副本,那麼我甚至不需要一個互斥體,因爲我不會寫它的結構,而從它讀取反正,不是嗎? – Kam 2012-03-06 11:48:16

+0

好吧,當你創建副本時(從IO線程本地到GUI線程結構),你仍然需要一個互斥體,但是你不需要一個互斥體,停止GUI線程從結構中隨意讀取它將始終處於一致的狀態。 即使在通知後經過10秒,您仍然無法確定GUI是否正在讀取,但可能並不安全地更新其結構。所以,在這個周圍放置一個互斥鎖,但除了那麼短的時間之外,GUI線程還是可以閱讀的。 – 2012-03-06 11:51:36

2

一種方法是讓IO線程將輸入數據發佈到GUI。只要你在IO線程上接收到數據,就將它打包在堆上的結構中,並將自定義消息和結構的地址一起發回到GUI線程。 IOW創建GUI線程,然後IO線程將GUI線程的句柄傳遞給IO線程,以用於將數據發送回GUI。這樣你就不需要關心互斥/關鍵部分,但是你可以使用現有的GUI消息隊列,或者根據你的項目應該運行的環境來創建你自己的環境。

+0

+1用於在正常GUI線程上使用消息排隊緩衝區實例/結構輸入隊列。 – 2012-03-07 00:08:35