【 聲明:著作權,歡迎轉載,請勿用於商業用途。 聯絡信箱:feixiaoxing @163.com】
在windows系統中,系統本身為我們提供了很多鎖。通過這些鎖的使用,一方面可以加強我們對鎖的認識,另外一方面可以提高代碼的效能和健壯性。常用的鎖以下四種:臨界區,互斥量,訊號量,event。
(1)臨界區
臨界區是最簡單的一種鎖。基本的臨界區操作有,
InitializeCriticalSection EnterCriticalSection LeaveCriticalSection DeleteCriticalSection
如果想要對資料進行互斥操作的話,也很簡單,這樣做就可以了,
EnterCriticalSection(/*...*/) do_something(); LeaveCriticalSection(/*...*/)
(2)互斥鎖
互斥鎖也是一種鎖。和臨界區不同的是,它可以被不同進程使用,因為它有名字。同時,擷取鎖和釋放鎖的線程必須是同一個線程。常用的互斥鎖操作有
CreateMutex OpenMutex ReleaseMutex
那麼,怎麼用互斥鎖進行資料的訪問呢,其實不難。
WaitForSingleObject(/*...*/); do_something(); ReleaseMutex(/*...*/);
(3)訊號量
訊號量是使用的最多的一種鎖結果,也是最方便的一種鎖。圍繞著訊號量,人們提出了很多資料互斥訪問的方案,pv操作就是其中的一種。如果說互斥鎖只能對單個資源進行保護,那麼訊號量可以對多個資源進行保護。同時訊號量在解鎖的時候,可以被另外一個thread進行解鎖操作。目前,常用的訊號量操作有,
CreateSemaphore OpenSemaphore ReleaseSemaphore
訊號量的使用和互斥鎖差不多。關鍵是訊號量在初始化的時候需要明確當前資源的數量和訊號量的初始狀態是什麼,
WaitForSingleObject(/*...*/); do_something(); ReleaseSemaphore(/*...*/);
(4)event對象
event對象是windows下面很有趣的一種鎖結果。從某種意義上說,它和互斥鎖很相近,但是又不一樣。因為在thread獲得鎖的使用權之前,常常需要main線程調用SetEvent設定一把才可以。關鍵是,在thread結束之前,我們也不清楚當前thread獲得event之後執行到哪了。所以使用起來,要特別小心。常用的event操作有,
CreateEvent OpenEvent PulseEvent ResetEvent SetEvent
我們對event的使用習慣於分成main thread和normal thread使用。main thread負責event的設定和操作,而normal thread負責event的等待操作。在CreateEvent的時候,要務必考慮清楚event的初始狀態和基本屬性。
對於main thread,應該這麼做,
CreateEvent(/*...*/); SetEvent(/*...*/); WaitForMultiObjects(hThread, /*...*/); CloseHandle(/*...*/);
對於normal thread來說,操作比較簡單,
while(1){ WaitForSingleObject(/*...*/); /*...*/ }
總結:
(1)關於臨界區、互斥區、訊號量、event在msdn上均有範例程式碼
(2)一般來說,使用頻率上訊號量 > 互斥區 > 臨界區 > 事件對象
(3)訊號量可以實現其他三種鎖的功能,學習上應有所側重
(4)紙上得來終覺淺,多實踐才能掌握它們之間的區別