1.互斥量
/*
*用於保護全局變量、硬件端口、管道識別碼、窗口客戶區
*多個線程共享資源時,優先考慮互斥量
*Mutex 可以跨進程使用,所以其名稱對整個系統而言是全局的
*param1:安全特徵,可以指定,也可以不填
*param2:線程所有權,設置爲TRUE,調用方立即獲得互斥量所有權
*param3:互斥量名稱必須指定
*/此處若把參數2設置爲TRUE,即創建線程互斥量,當前線程即獲取該互斥量,需在同一個線程釋放 h_Mutex = CreateMutex(NULL, FALSE, "mutex");
/*
*爲現有的已經存在的互斥量對象創建一個新句柄
*param1:請求訪問方式 安全特徵
* MUTEX_ALL_ACCESS 請求對互斥體的完全訪問
* MUTEX_MODIFY_STATE 允許使用 ReleaseMutex 函數
* SYNCHRONIZE 允許互斥體對象同步使用
*
*param2:如希望子進程能夠繼承句柄,則爲TRUE
*param3:要打開對象的名字
*互斥量不存在返回失敗ERROR_FILE_NOT_FOUND 必須釋放互斥量ReleaseMutex
*/HANDLE ret = OpenMutex(MUTEX_ALL_ACCESS, TRUE, "mutex");
等待互斥量
WaitForSingleObject(h_Mutex, INFINITE);//等待互斥量
釋放互斥量
BOOL ret = ReleaseMutex(h_Mutex);
2.信號量
/*
*用於保護全局變量、硬件端口、管道識別碼、窗口客戶區
*多個線程共享資源時,優先考慮互斥量
*Semaphores 可以跨進程使用,所以其名稱對整個系統而言是全局的
*param1:安全特徵,可以指定,也可以不填 NULL默認安全方式
* MUTEX_ALL_ACCESS 請求對互斥體的完全訪問
* MUTEX_MODIFY_STATE 允許使用 ReleaseMutex 函數
* SYNCHRONIZE 允許互斥體對象同步使用
*param2:初始數目以確定信號量初始觸發狀態,設置爲0,爲未觸發狀態,如果當前資源計數等於0,那麼信號量處於未觸發狀態;那麼系統會讓調用線程進入等待狀態
*param3:可同時持有信號量所有權的最多線程對象數目
*param4:必須提供信號量名
*/創建信號量
h_Semaphore = CreateSemaphore(NULL, 0, 1, "semaphore");
等待信號量
WaitForSingleObject(h_Semaphore, INFINITE);//等待互斥量
釋放信號量
BOOL ret = ReleaseSemaphore(h_Semaphore, 1, NULL);
3.事件對象
/*
*param1:安全特徵,可以指定,也可以不填 NULL默認安全方式.確定返回的句柄是否可被子進程繼承,是NULL,此句柄不能被繼承
*param2:用於確定事件對象,TRUE代表必須把ResetEvent中事件對象設置爲未觸發狀態.(TRUE)必須使用ResetEvent()手動重置爲無信號狀態
* FALSE當一個等待線程被釋放時,自動重置狀態爲無信號狀態
*param3:設置事件初始狀態,爲TRUE則表示立即設置爲觸發狀態
*param4:必須提供事件名
*/創建事件對象
h_Event = CreateEvent(NULL, TRUE,TRUE,"event");
將事件對象設置爲已觸發狀態
BOOL ret = SetEvent(h_Event);
將事件對象設置爲未觸發狀態
BOOL ret = ResetEvent(h_Event);
脈衝事件,將事件對象設置爲已觸發狀態,然後將其重置爲未觸發狀態,釋放特定數量的等待線程
BOOL ret = PulseEvent(h_Event);
事件對象在創建時候的四種情況分析,針對參數二和參數三
1.人工重置事件:使用手動重置爲無信號狀態,初始化時有信號狀態,調用WaitForSingleObject不會等待
CreateEvent(NULL, TRUE, TRUE, NULL)
2.人工重置事件:使用手動重置爲無信號狀態,初始化時爲無信號狀態 調用WaitForSingleObject會一直等待
CreateEvent(NULL, TRUE, FALSE, NULL);
若某個線程調用WaitForSingleObject(hEvent,INFINITE) 則會一直等待,需要先調用SetEvent()設置爲有信號狀態,才能繼續執行,否則一直在等待;ResetEvent(),要想有信號需調用SetEvent(hEvent)
3.自動重置事件:當一個等待線程被釋放時,自動重置爲無信號狀態,初始是有信號狀態,調用WaitForSingleObject不會等待
CreateEvent(NULL, FALSE, TRUE, NULL);
另一個線程若還需要等到通知,即在當前線程調用SetEvent()
4.自動重置事件:線程釋放後自動重置爲無信號狀態,初始化時爲無信號狀態
CreateEvent(NULL, FALSE, FALSE, NULL);
4.臨界區
臨界區的功能與互斥量相同,同一時刻只被一個線程擁有
運行速度更快,開銷更小
開始臨界區對象處於未觸發狀態,被釋放後處於觸發狀態臨界區創建以及使用方式。
1.先聲明臨界區對象
2.初始化
3.讓線程進入臨界區
4.任務完成後,讓線程離開臨界區
5.釋放資源//1
CRITICAL_SECTION c_section;
//2
InitializeCriticalSection(&c_section);
//3
EnterCriticalSection(&c_section); //或者 TryEnterCriticalSection(&c_section);
//4
LeaveCriticalSection(&c_section);
//5
DeleteCriticalSection(&c_section);