臨界區(qū)
定義臨界區(qū)變量
CRITICAL_SECTION gCriticalSection; |
通常情況下,CRITICAL_SECTION結(jié)構(gòu)體應(yīng)該被定義為全局變量,以便于進程中的所有線程方便地按照變量名來引用該結(jié)構(gòu)體。
初始化臨界區(qū)
VOID WINAPI InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection //指向程序員定義的CRITICAL_SECTION變量 ); |
該函數(shù)用于對pcs所指的CRITICAL_SECTION結(jié)構(gòu)體進行初始化。該函數(shù)只是設(shè)置了一些成員變量,它的運行一般不會失敗,因此它采用了VOID類型的返回值。該函數(shù)必須在任何線程調(diào)用EnterCriticalSection函數(shù)之前被調(diào)用,如果一個線程試圖進入一個未初始化的CRTICAL_SECTION,那么結(jié)果將是很難預(yù)計的。
刪除臨界區(qū)
VOID WINAPI DeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection //指向一個不再需要的CRITICAL_SECTION變量 ); |
進入臨界區(qū)
VOID WINAPI EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection //指向一個你即將鎖定的CRITICAL_SECTION變量 ); |
離開臨界區(qū)
VOID WINAPI LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection //指向一個你即將離開的CRITICAL_SECTION變量 ); |
使用臨界區(qū)編程的一般方法是:
void UpdateData() { EnterCriticalSection(&gCriticalSection); ...//do something LeaveCriticalSection(&gCriticalSection); } |
關(guān)于臨界區(qū)的使用,有下列注意點:
(1)每個共享資源使用一個CRITICAL_SECTION變量;
(2)不要長時間運行關(guān)鍵代碼段,當(dāng)一個關(guān)鍵代碼段長時間運行時,其他線程就會進入等待狀態(tài),這會降低應(yīng)用程序的運行性能;
(3)如果需要同時訪問多個資源,則可能連續(xù)調(diào)用EnterCriticalSection;
(4)Critical Section不是OS核心對象,如果進入臨界區(qū)的線程"掛"了,將無法釋放臨界資源。這個缺點在Mutex中得到了彌補。
互斥 互斥量的作用是保證每次只能有一個線程獲得互斥量而得以繼續(xù)執(zhí)行,使用CreateMutex函數(shù)創(chuàng)建:
HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, // 安全屬性結(jié)構(gòu)指針,可為NULL BOOL bInitialOwner, //是否占有該互斥量,TRUE:占有,F(xiàn)ALSE:不占有 LPCTSTR lpName //信號量的名稱 );
|
Mutex是核心對象,可以跨進程訪問,下面的代碼給出了從另一進程訪問命名Mutex的例子:
HANDLE hMutex; hMutex = OpenMutex(MUTEX_ALL_Access, FALSE, L"mutexName"); if (hMutex){ … } else{ … } |
相關(guān)API:
BOOL WINAPI ReleaseMutex( HANDLE hMutex ); |
使用互斥編程的一般方法是:
void UpdateResource() { WaitForSingleObject(hMutex,…); ...//do something ReleaseMutex(hMutex); } |
互斥(mutex)內(nèi)核對象能夠確保線程擁有對單個資源的互斥訪問權(quán)。互斥對象的行為特性與臨界區(qū)相同,但是互斥對象屬于內(nèi)核對象,而臨界區(qū)則屬于用戶方式對象,因此這導(dǎo)致mutex與Critical Section的如下不同:
(1) 互斥對象的運行速度比關(guān)鍵代碼段要慢;
(2) 不同進程中的多個線程能夠訪問單個互斥對象;
(3) 線程在等待訪問資源時可以設(shè)定一個超時值。
下圖更詳細地列出了互斥與臨界區(qū)的不同: