2016-04-25 39 views
0

我有每50毫秒後轟出WM_TIMER回調函數運行,這裏面我創建一個線程只是爲了保證UI線程不阻止,這些線程我線程安全的共享內存操作使用互斥體對象。限制線程的數量從定時器

我的問題是什麼時候創建了新線程,而且之前的線程還沒有完成,他們在線WaitForSingleObject(ghMutex, INFINITE)之後轉到了等待狀態,因爲內存中這個活動線程的數目將呈指數級增長,可能我應該這樣做,我認爲用定時器可以更好地管理頻率。

我還試圖用一個線程計數器(講述活動線程的數量),並從回調函數返回,如果計數器大於零,按我的理解,這是不是線程安全的。

我應該怎麼做,以保持只有一個線程,如果一個線程將無法獲取互斥鎖,那麼就應該終止,而不是等待隨時運行,例如。

+1

你可以用單線程來完成,不需要WM_TIMER。你的線程會有一個主循環,在頂部它會記住使用GetCurrentTime()的開始時間,然後執行其任務。在執行它之後,檢查你是否應該:: Sleep()這個線程的剩餘時間(直到50ms),或者繼續循環。但是你不會同時執行多個線程,所以我不確定這是否是你想要的。 – marcinj

+0

@MarcinJędrzejewski是的,我不需要在任何時候執行多個線程,順便說一句,如何將性能,因爲在這裏我有幾個GetCurrentTime()和一個IF語句在這裏。 –

+1

你肯定是做錯了。單線程是你需要的。大概。我們不知道你的實際問題。 –

回答

2

這裏是你可以做什麼,根據您的描述和addtional評論:

擁有:

  • 一個用於GUI線程(接收計時器事件)
  • 另一個線程的處理。
  • 事件(與CreateEvent創建)

處理線程將有一個大的無限循環for(;;)通過等待活動開始,然後做所需的處理。定時器事件,而不是每隔50ms觸發一個新線程,只會調用SetEvent來觸發處理線程。

這樣,您不能同時擁有多個「處理器」。如果進行的時間超過50毫秒,則丟棄。

如果每個事件需要50ms以上進行,則可以有一個以上的處理線程+事件,並從該定時器觸發它們可選地在一個循環的方式(週期的波谷它們)。

+0

看起來像一個乾淨的解決方案,你說setevent不堆積如果不處理? –

+1

是的,在內部,它是一個布爾(有信號/無信號)。如果事件未被清除,則同一對象上的多個SetEvent將不起作用。 – dim

2

在我看來,你違反了線程的最基本的原則之一(雖然@昏暗的回答是一種進步,它仍然在做同樣的)。要記住的最大要點之一是線程應儘可能獨立運行。理想情況下,您希望儘量減少線程之間的同步和通信,儘可能降低他們完成工作所需的時間。

在這種情況下,最小似乎是「無」。主線程必須創建工作線程。在那之後,你所描述的都不需要任何進一步的溝通。

至少據我所知,這裏的目的是使工作線程在50周毫秒的時間間隔做一些處理。假設這是正確的,你似乎完全沒有從UI線程中獲得任何東西。相反,你應該有一個啓動,並在一個循環做像一個(也是唯一一個)工作線程:

  1. 記錄當前時間
  2. 執行它的處理
  3. 睡了50餘MS開始以來(如有必要)
  4. 重複

雖然沒有描述任何事情,在這裏,我看到了(可能)需要線程間通信的唯一的地方是這個工作線程告訴 UI線程完成一輪處理,UI可以使用這些數據更新UI。我不知道你的情況下需要什麼樣的表格(並且它根本不需要可能),但我至少可以看到可能需要。然而,僅僅讓線程每隔50毫秒執行一次操作就沒有足夠的理由來進行任何類型的線程間通信(更不用說每隔50毫秒創建一個新線程的開銷,然後增加更多開銷以確保您一次只有一個工作線程)。

+0

我真的不需要來回通信,因爲線程直接更新主線程使用的變量,順便說一句,我們應該信任線程間通信,有可能會跳過一些事件? –

+0

這不是一個「有些事件可以跳過」的問題。只是一個事件只有兩個狀態:設置和清除。如果你設置了一個已經設置好的信號,它就保持設置。它的作用就像一個'bool'變量 - 如果它已經是'true',並且給它賦值'true',那不會改變任何東西。 –