前面讲的三种保持线程同步的方法是临界区,事件,互斥.它们都有点类似,就是确保一次只有一个线程访问资源,独占一个资源.
而信号量就与它们不同,它是可以让很多线程同时访问一个资源,但是限制一次同时访问的数量.这样的资源一般是只读,所以不会造成资源的混乱.最简单的例子就是数据库中表的读操作,可以多个线程同时去读.而写可不行(只能一次让一个去写).
在这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();
}