HANDLE WINAPI CreateSemaphore(
_In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes
_In_ LONG lInitialCount,
_In_ LONG lMaximumCount,
_In_opt_ LPCTSTR lpName
);
第一個參數:安全屬性,如果為NULL則是默認安全屬性
第二個參數:信號量的初始值,要>=0且<=第三個參數
第三個參數:信號量的最大值
第四個參數:信號量的名稱
返回值:指向信號量的句柄,如果創建的信號量和已有的信號量重名,那么返回已經存在的信號量句柄
使用方法:
1、創建一個信號量:CreateSemaphore;
2、打開一個已經存在的信號量:OpenSemaphore;
3、獲得信號量的一個占有權:WaitForSingleObject、WaitForMultipleObjects 等一類等待的函數……(可能造成阻塞);
4、釋放信號量的占有權:ReleaseSemaphore;
5、關閉信號量:CloseHandle;
※ 命名標准:Semaphores 可以跨進程使用,所以其名稱對整個系統而言是全局的,所以命名不要過於普通,類似:Semaphore、Object 等。
最好想一些獨一無二的名字等!
固有特點(優點+缺點):
1、是一個系統核心對象,所以有安全描述指針,用完了要 CloseHandle 關閉句柄,這些是內核對象的共同特征;
2、因為是核心對象,所以執行速度稍慢(當然只是相比較而言);
3、因為是核心對象,而且可以命名,所以可以跨進程使用;
4、Semaphore 使用正確的情況下不會發生死鎖;
5、在“等待”一個 信號量 的時候,可以指定“結束等待”的時間長度;
6、非排他性的占有,跟 Critical Sections 和 Mutex 不同,這兩種而言是排他性占有,
即:同一時間內只能有單一線程獲得目標並擁有操作的權利,而 Semaphores 則不是這樣,
同一時間內可以有多個線程獲得目標並操作!
信號量沒有線程所有權屬性,即一個線程獲得某個信號量后,在他釋放該信號量之前,他不能再次進入信號量保護的區域
信號量的使用規則:
1. 如果當前資源計數大於0,那么信號量處於觸發狀態;
2. 如果當前資源計數等於0,那么信號量處於未觸發狀態;那么系統會讓調用線程進入等待狀態。
CreateSemaphore(NULL,0,1,NULL); 當第二個參數為0時,調用線程就會進入等待狀態
3. 系統絕對不會讓當前資源計數變為負數;
4. 當前資源計數絕對不會大於最大資源計數。
#include <iostream> #include <windows.h> using namespace std; const int g_Number = 3; DWORD WINAPI ThreadProc1(__in LPVOID lpParameter); DWORD WINAPI ThreadProc2(__in LPVOID lpParameter); DWORD WINAPI ThreadProc3(__in LPVOID lpParameter); HANDLE hSemp1,hSemp2,hSemp3; int main() { hSemp1 = CreateSemaphore(NULL,1,1,NULL); hSemp2 = CreateSemaphore( NULL,1,1,NULL); hSemp3 = CreateSemaphore(NULL,1,1,NULL); HANDLE hThread[ g_Number ] = {0}; int first = 1, second = 2, third = 3; hThread[ 0 ] = CreateThread(NULL,0,ThreadProc1,(LPVOID)first,0,NULL); hThread[ 1 ] = CreateThread(NULL,0,ThreadProc2,(LPVOID)second,0,NULL); hThread[ 2 ] = CreateThread(NULL,0,ThreadProc3,(LPVOID)third,0,NULL); WaitForMultipleObjects(g_Number,hThread,TRUE,INFINITE); CloseHandle( hThread[0] ); CloseHandle( hThread[1] ); CloseHandle( hThread[2] ); CloseHandle( hSemp1 ); CloseHandle( hSemp2 ); CloseHandle( hSemp3 ); return 0; } DWORD WINAPI ThreadProc1(__in LPVOID lpParameter) { WaitForSingleObject(hSemp1, INFINITE);//等待信號量 cout<<(int)lpParameter<<endl; ReleaseSemaphore(hSemp1,1,NULL);//釋放信號量 return 0; } DWORD WINAPI ThreadProc2(__in LPVOID lpParameter) { WaitForSingleObject(hSemp2, INFINITE);//等待信號量 cout<<(int )lpParameter<<endl; ReleaseSemaphore(hSemp2,1,NULL);//釋放信號量 return 0; } DWORD WINAPI ThreadProc3(__in LPVOID lpParameter) { WaitForSingleObject( hSemp3, INFINITE);//等待信號量 cout<<(int)lpParameter<<endl; ReleaseSemaphore(hSemp3,1,NULL);//釋放信號量 return 0; }