2012-07-26 59 views
0

我目前有一個程序一次運行約20個線程。我對多線程相當陌生,所以我對正確的數據保護有點困惑。事件還是互斥?

目前,我的線程使用事件作爲數據鎖定解鎖。我選擇在關鍵部分使用它,因爲大多數數據僅在兩個或三個線程之間共享,因此阻止單個線程讀取,而通過停止所有20個線程寫入時,這看起來很浪費。我只是因爲我無法(很容易地)找到一個明確解釋Mutex如何工作以及如何實現Mutex的源代碼,因此我使用了互斥事件。

我爲我的多線程使用Win32 API。在我當前的設置中,我使用事件來鎖定數據,所以我的事件就像「DataUnlock」。如果沒有設置,我知道數據正在處理。設置時,我知道可以處理數據。所以我的臨時數據鎖看起來像這樣。

WaitForSingleObject(DataUnlock,INFINITE); //Wait until the Data is free 
ResetEvent(DataUnlock);      //Signal that the data is being worked on 
...work on Data...  
SetEvent(DataUnlock);      //Signal that the data is free to use 

我的第一個問題是:當只有兩個線程訪問數據時,這與使用Mutex一樣好嗎(高效)?第二:如果等待訪問數據的兩個以上的線程在釋放數據時會觸發這兩個線程(兩者都會在等待ResetEvent之前通過等待)?如果是這樣,互斥體會有同樣的問題嗎?

最後:如果互斥量更好,我將如何去實現一個(鏈接或解釋將不勝感激)?

謝謝!

回答

0

我不認爲事件方法是保護數據的最佳方式。

看看Mutex ObjectsUsing Mutex Objects瞭解互斥鎖。

  1. 你的一個線程必須創建一個互斥鎖。 CreateMutex function返回互斥對象的句柄。您可以將句柄作爲參數傳遞給處理數據的線程。
  2. 使用WaitForSingleObject function來等待互斥鎖,然後處理您的數據。撥打ReleaseMutex function釋放互斥鎖。當一個互斥體被釋放時,下一個等待函數將獲得互斥體。
  3. 如果要由多個進程的線程訪問數據,則必須使用已命名的互斥鎖。

查看Critical Section Objects瞭解關鍵部分同步。

如果你想有

  1. 一個關鍵部分必須通過向InitializeCriticalSection function調用創建。
  2. 在處理數據之前,請在所有地方使用EnterCriticalSection function
  3. LeaveCriticalSection function發佈臨界區釋放對象。在完成數據後使用此調用。

關鍵部分只能由擁有的線程輸入。一旦線程獲得臨界區對象,其他線程就無法訪問您的數據。其他線程將阻止在EnterCriticalSection()的調用。然而,擁有關鍵部分的線程可以不止一次地對EnterCriticalSection()進行連續調用。應注意撥打LeaveCriticalSection()一次致電EnterCriticalSection()

你的例子會讓所有等待事件的線程處理你的數據。而且只有數據證明自己是否已經處理了任何類型的數據。這取決於你, 如何確定做了什麼以及還需要做什麼。如果你有很多線程在等待你的事件,你不能告訴獲取訪問的順序。


我會推薦使用臨界區對象。它重量輕,使用相對簡單。有關如何使用臨界截面對象的示例,請參見Using Critical Section Objects