前面講的三種保持線程同步的方法是臨界區,事件,互斥.它們都有點類似,就是確保一次只有一個線程訪問資源,獨佔一個資源.
而訊號量就與它們不同,它是可以讓很多線程同時訪問一個資源,但是限制一次同時訪問的數量.這樣的資源一般是唯讀,所以不會造成資源的混亂.最簡單的例子就是資料庫中表的讀操作,可以多個線程同時去讀.而寫可不行(只能一次讓一個去寫).
在這Server的編程中蠻有用,限制同時訪問server的用戶端是多少個.
Win32 API中的semphore
HANDLE hSemaphore;
CString szInfo = _T("I am useful info");
void MainTest(){
hSemaphore = CreateSemaphore(NULL,2,2,NULL); //只能同時兩個線程並發訪問
AfxBeginThread(FunOne,NULL);
AfxBeginThread(FunTwo,NULL);
//如果再多加一個線程有可能出錯,也可能不.假如恰好三個線程同時訪問就出錯,如果前面的某個已經訪問完了那不會出錯
}
UINT FunOne(LPVOID pParam){
WaitForSingleObject(hSemaphore, INFINITE);
CString info = szInfo;
ReleaseSemaphore(hSemaphore, 1, NULL);
}
UINT FunTwo(LPVOID pParam){
WaitForSingleObject(hSemaphore, INFINITE);
CString info = szInfo;
ReleaseSemaphore(hSemaphore, 1, NULL);
}
MFC中的semphore類
CSemaphore g_cSHE(2,2);
CString szInfo = _T("I am useful info");
void MainTest(){
AfxBeginThread(FunOne,NULL);
AfxBeginThread(FunTwo,NULL);
//如果再多加一個線程有可能出錯,也可能不.假如恰好三個線程同時訪問就出錯,如果前面的某個已經訪問完了那不會出錯
}
UINT FunOne(LPVOID pParam){
g_cSHE.Lock();
CString info = szInfo;
g_cSHE.Unlock();
}
UINT FunTwo(LPVOID pParam){
g_cSHE.Lock();
CString info = szInfo;
g_cSHE.Unlock();
}