多线程(10)多线程同步之信号量(windows实现)
1.概念
信号量:解决多个线程同时访问一个共享资源问题。
2.出现原因
锁机制只能判断临界资源是否被占用,所以他解决了互斥问题,但是他不能用于同步问题。
互斥量用于线程的互斥,信号量用于线程的同步。
3.互斥量和信号量的根本区别
互斥量用于线程的互斥,信号量用于线程的同步。
也就是互斥和同步之间的区别。
4.接口函数
1、创建一个信号量:CreateSemaphore;
2、打开一个已经存在的信号量:OpenSemaphore;
3、获得信号量的一个占有权:WaitForSingleObject、WaitForMultipleObjects 等一类等待的函数……(可能造成阻塞);
4、释放信号量的占有权:ReleaseSemaphore;
5、关闭信号量:CloseHandle
5. 信号量的使用规则
- 如果当前资源计数大于0,那么信号量处于触发状态;
- 如果当前资源计数等于0,那么信号量处于未触发状态;
那么系统会让调用线程进入等待状态。
6.代码例子
//-------------semphone--------------------------------------------------------
HANDLE hSem,hSemOne,hSemTwo,hSemThree;
DWORD WINAPI semThreadOne(LPVOID lp)
{
while (1)
{
//信号量减1,如果等于0就进入睡眠,待大于0之后再减
WaitForSingleObject(hSem,INFINITE);
if (g_num>0)
{
g_num--;
cout<<"sem thread one "<<g_num<<endl;
}
else
{
return 0;
}
//释放信号量 信号量+1
ReleaseSemaphore(hSem,1,NULL);
}
return 0;
}
DWORD WINAPI semThreadTwo(LPVOID lp)
{
while (1)
{
WaitForSingleObject(hSem,INFINITE);
if (g_num>0)
{
g_num--;
cout<<"sem thread two "<<g_num<<endl;
}
else
{
return 0;
}
ReleaseSemaphore(hSem,1,NULL);
}
return 0;
}
DWORD WINAPI semThreadThree(LPVOID lp)
{
while (1)
{
WaitForSingleObject(hSem,INFINITE);
if (g_num>0)
{
g_num--;
cout<<"sem thread three "<<g_num<<endl;
}
else
{
return 0;
}
ReleaseSemaphore(hSem,1,NULL);
}
return 0;
}
int semTest()
{
hSem=CreateSemaphore(0,1,3,0);
hSemOne=CreateThread(0,0,semThreadOne,0,0,0);
hSemTwo=CreateThread(0,0,semThreadTwo,0,0,0);
hSemThree=CreateThread(0,0,semThreadThree,0,0,0);
WaitForSingleObject(hSemOne,INFINITE);
WaitForSingleObject(hSemTwo,INFINITE);
WaitForSingleObject(hSemThree,INFINITE);
CloseHandle(hSemOne);
CloseHandle(hSemTwo);
CloseHandle(hSemThree);
CloseHandle(hSem);
return 0;
}
7. 参考
http://www.blogjava.net/fhtdy2004/archive/2009/07/05/285519.html
https://www.cnblogs.com/ssss429170331/p/5514769.html
https://www.cnblogs.com/zhangbaochong/p/5800650.html