線程之間的同步使用一些核心對象:如thread, process, evnet, mutex, semaphore.
線上程之間使用等待函數如WaitForSingleObjects, WaitForMultipleObjects.
等待函數使用核心對象的handle作為參數,如果handle被激發,則執行下一步。
handle被激發的條件: (handle是一段記憶體指標,為了掩藏內部實現而作的一個類型轉化指標)
激發:---我的理解是資源未被戰勝。
未激發: ---資源正在被佔用。
eg:
1)thread, process被終止,則激發。
2)event: 要通過它的API來手動激發,是最靈活的激發方式,可被所有線程使用。
3)mutex: 沒被任何線程所擁有,則激發。
1)臨界區: CRITICAL_SECTION
適用範圍: 單一進程的各線程之間用來排它性佔有
特性: 局部性對象; 快速而有效. 無法監測是否被線程放棄
函數: EnterCriticalSection LeaveCriticalSection
2)Mutex:
適用範圍: 不同線程之間用來排它性佔有
特性: 核心對象, 可以使用wait進行等待,只能被擁有線程所釋放
函數:CreateMutex ReleaseMutex
3)semaphore: 訊號量
適用範圍: 用來限制資源佔用
特性: 核心對象,沒有擁有者,任何線程都可釋放
函數:CreateSemaphore OpenSemaphore ReleaseSemaphore
4)Event:
適用範圍: 同來控制對象訊號的接收,常與訊號系統結合起來
特性: 核心對象
函數: CreateEvent OpenEvent PulseEvent SetEvent ResetEvent
5)Interlocked
簡單的原子操作,如寫檔案中對檔案中位元組範圍的鎖定_locking
NOTE: 線程同步中很重要的可歸納為鎖系統lock和訊號系統signal
lock包括:CRITICAL_SECTION, Mutex,
wait function:
WaitForMultipleObjects WaitForSingleObject Sleep
6)completion port
適用範圍: 網路非同步接收,包括檔案讀寫
特性:由OS來控制讀寫, 是windows平台最有效同步機制,相當於linux的AIO或者非阻塞socket+epoll
函數: CreateIoCompletionPort GetQueuedCompletionStatus
樣本1: event
//事件機制: 設定一個全域event對象,這個只能等待最多64個對象,而且要用WaitForMultipleObjects來監視線
程handle數組. 不如完全連接埠completion port
HANDLE ghWriteEvent;
HANDLE ghThreads[THREADCOUNT];
//(1)建立個手動事件,一開始不接受任何訊號no signel
//ResetEvent: 用來訊號重設,同CreateEvent or OpenEvent
ghWriteEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual-reset event
FALSE, // initial state is nonsignaled
TEXT("WriteEvent") // object name
);
//(2)產生一堆線程,設定事件響應訊號signal,
if (! SetEvent(ghWriteEvent) )
{
printf("SetEvent failed (%d)/n", GetLastError());
return;
}
//(3)設定線程等待事件,所有線程都接到這個事件,,這裡對線程進行了同步,只有所有線程都執行了,才執行下一步
dwWaitResult = WaitForMultipleObjects(
THREADCOUNT, // number of handles in array
ghThreads, // array of thread handles
TRUE, // wait until all are signaled
INFINITE);
{
//(3.1)其中每個線程函數都在等待事件對象,這裡也對線程進行了同步,只有得到signal的線程才執行下一步
dwWaitResult = WaitForSingleObject(
ghWriteEvent, // event handle
INFINITE); // indefinite wait
}
//(4)關閉了這個全域事件 == CloseHandle(ghWriteEvent)
CloseEvents();
樣本2: completion port
(1) 建立完成連接埠, 與一個監聽socket發生關聯 CreateIoCompletionPort
(2) 產生一堆線程,讓線程在完全連接埠迴圈等待. CreateThread--(WorkerThread)--
GetQueuedCompletionStatus
(3) 接收監聽socket的讀寫請求accept,將accept socket與完全連接埠關聯,....?
參考資料:
http://msdn2.microsoft.com/en-us/library/ms686360(VS.85).aspx