標籤:說明 event 互斥對象 section 實踐 and 控制代碼 leave ...
在Windows環境下針對多線程同步與互斥操作的支援,主要包括四種方式:臨界區(CriticalSection)、互斥對象(Mutex)、訊號量(Semaphore)、事件對象(Event)。下面分別針對這四種方式作說明:
(1)臨界區(CriticalSection)
每個進程中訪問臨界資源的那段代碼稱為臨界區(臨界資源是一次僅允許一個進程使用的共用資源)。每次只准許一個進程進入臨界區,進入後不允許其他進程進入。不論是硬體臨界資源,還是軟體臨界資源,多個進程必須互斥地對它進行訪問。Windows環境下臨界區的基本操作有以下幾個:
CRITICAL_SECTION CriticalSection;InitializeCriticalSection(&CriticalSection);EnterCriticalSection(&CriticalSection);LeaveCriticalSection(&CriticalSection);DeleteCriticalSection(&CriticalSection);
(2)互斥對象(Mutex)
在編程中,引入了對象互斥對象(也叫互斥鎖)的概念,來保證共用資料操作的完整性。每個對象都對應於一個可稱為“互斥鎖”的標記,這個標記用來保證在任一時刻,只能有一個線程訪問該對象。互斥對象的操作介面有以下幾個:
CreateMutexOpenMutexReleaseMutex
在使用互斥對象的時候藉助WaitforSingleObject,例如:
WaitForSingleObject(/*...*/); do_something();ReleaseMutex(/*...*/);
(3)訊號量(Semaphore)
訊號量有時被稱為號誌,是在多線程環境下使用的一種設施,它負責協調各個線程,以保證它們能夠正確、合理的使用公用資源。也是作業系統中用於控制進程同步互斥的量。訊號量分為單值和多值兩種,前者只能被一個線程獲得,後者可以被若干個線程獲得。與互斥對象相比,訊號量就好比是可以容納N多個人的房子允許多個人同時進入(數量有限制而已),而互斥對象就只能容納一個人的小房子,同一時刻只能一個人使用。
Windows環境下的訊號量操作介面包括:
CreateSemaphoreOpenSemaphoreReleaseSemaphore
訊號量的使用方式與互斥對象差不多,只不過在初始化的時候需要指定訊號的個數:
WaitForSingleObject(/*...*/); do_something();ReleaseSemaphore(/*...*/);
(4)事件對象(Event)
Event對象是Windows下面很有趣的一種鎖結果。從某種意義上說,它和互斥鎖很相近,但是又不一樣。因為線上程獲得鎖的使用權之前,常常需要某一個線程(可能是主線程也可能是其他線程)調用SetEvent設定一下才行。關鍵是,線上程結束之前,我們也不清楚當前線程獲得Event之後執行到哪了。所以使用起來,要特別小心。常用的Event對象操作有:
CreateEventOpenEventPulseEventResetEventSetEvent
主線程一般可以這樣做:
CreateEvent(/*...*/); // 建立事件對象SetEvent(/*...*/); // 設定訊號WaitForMultiObjects(hThread, /*...*/); // 等待線程結束CloseHandle(/*...*/); // 關閉線程控制代碼
而被啟動的線程一般要等待某個事件再進行動作:
while(1){ WaitForSingleObject(/*...*/); // 等待事件 /*...*/}
總結:
(1)關於臨界區、互斥區、訊號量、Event在msdn上均有範例程式碼;
(2)一般來說,使用頻率上訊號量 > 互斥對象 > 臨界區 > 事件對象
(3)訊號量可以實現其他三種鎖的功能,學習上應有所側重
(4)紙上得來終覺淺,多實踐才能掌握它們之間的區別
多線程編程之Windows同步方式