一、互斥 mutex (mutual exclusion)
1. 一個(gè)時(shí)間,只能有一個(gè)線程擁有 mutex
2. mutex 跨進(jìn)程使用,Critical section 只能在同一個(gè)進(jìn)程使用
3. mutex 可指定等待時(shí)間
4. mutex 是內(nèi)核對(duì)象,critical section 直接在 user mode 操作
5. 生成一個(gè) mutex:
HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName);
調(diào)用成功返回 handle; 否則返回 NULL, 可通過(guò) GetLastError() 得到 error code
example:
---------------
HANDLE hMutex;
hMutex = CreateMutex(NULL, FALSE, "demo");
CloseHandle(hMutex);
6. mutex 未被任何線程擁有時(shí),且有一個(gè)線程 wait 它時(shí), 它便處于激發(fā)狀態(tài); 一個(gè)線程等待一個(gè)未被激發(fā)的 mutex, 便稱(chēng)其進(jìn)入了阻塞(blocking)狀態(tài)
7. 釋放 mutex
BOOL ReleaseMutex(HANDLE hMutex);
成功 - TRUE, 失敗 - FALSE
8. API CreateMutex 為什么有一個(gè)最初擁有者?
API CreateMutex 提供參數(shù) BOOL bInitialOwner 的目的是要避免 race condition 的發(fā)生. 請(qǐng)看如下示例:
HANDLE hMutex = CreateMutex(NULL, FALSE, "sample");
int result = WaitForSingleObject(hMutex, INFINITE);
如果在 CreateMutex 完成之后,發(fā)生 context switch, CPU 被切換到另一線程, 則其它進(jìn)程可能在 mutex 的產(chǎn)生者調(diào)用 WaitForSingleObject()
之前鎖住這個(gè) mutex 對(duì)象. 這就會(huì)引發(fā)竟?fàn)?br>
二、信號(hào)量 (Semaphore)
1. 產(chǎn)生信號(hào)量
HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpAttributes, LONG lInitialCount, LONG lMaxCount, LPCTSTR lpName);
成功 - 返回一個(gè) handle. 失敗 - 返回一個(gè) NULL, 可通過(guò) GetLastError() 獲得 error code
一旦 semaphore 的現(xiàn)值降到 0, 就表示資源耗盡.此時(shí)如果任何一個(gè)線程如果調(diào)用 wait...() 函數(shù)則必須等待,直到某個(gè)鎖定被解除。
2. 解除鎖定
BOOL ReleaseSamephore(HANDLE hSamephore, LONG lReleaseCount, LPLONG lpPreviousCount);
此函數(shù)將 semaphore 的現(xiàn)值增加一個(gè)定額, 通常是 1, 并返回 semaphore 的前一個(gè)值。
三、事件對(duì)象(Event)
1. 什么是 Event
一種核心對(duì)象, 它存在的目的就是成為激發(fā)態(tài)或未激發(fā)態(tài), 這兩種狀態(tài)完全由程序來(lái)控制。你可以告訴一個(gè) event 去做什么事情,什么時(shí)候去做.
2. 產(chǎn)生 event
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName)
lpEventAttributes: 安全屬性, NULL 指默認(rèn)屬性.
bManualReset: 如果為 FALSE, 表示這個(gè) event 變成激發(fā)態(tài)(因?yàn)閱拘岩粋€(gè)線程)之后,自動(dòng)重置為非激發(fā)態(tài); 如果為 TRUR, 則不會(huì)自動(dòng)重置, 需要程序操作(ResetEvent())才可變成非激發(fā)態(tài)
bInitialState: TRUE - 一開(kāi)始處于激發(fā)態(tài); FALSE - 一開(kāi)始處于非激發(fā)態(tài)
lpName: Event 對(duì)象的名稱(chēng)
調(diào)用成功返回 event handle, GetLastError() 會(huì)返回 0; 失敗-返回 NULL, 可通過(guò) GetLastError() 獲得錯(cuò)誤碼.
四、Interlock variables
1. 同步機(jī)制最簡(jiǎn)單的類(lèi)型是使用 Interlock 函數(shù), 它對(duì)標(biāo)準(zhǔn)的 32 位變量進(jìn)行操作,這些函數(shù)沒(méi)有提供 "等待" 機(jī)能,它只是保證對(duì)某個(gè)選定的變量的存取 "一個(gè)一個(gè)按順序來(lái)"。
2. Interlock variables 主要用于引用記數(shù)。允許對(duì) 4 字節(jié)的數(shù)值有些基本的同步操作, 不需要用到 Critical Section 或 mutex 之類(lèi)(開(kāi)銷(xiāo)大)。
3. 所謂的 Interlock 函數(shù)主要有兩個(gè):
LONG InterlockedIncrement(LPLONG lpTarget)
LONG InterlockedDecrement(LPLONG lpTarget)
變量經(jīng)過(guò)運(yùn)算(加 1 或 減 1),如果等于 0, 就返回 0;大于 0 傳回一個(gè)正值;小于 0 傳回一個(gè)負(fù)值。