信号量
信号量在WIN32系统中是核心对象,故其用法同其他同步机制类似,但可应用于多个线程同步运行,即同时有至多有限个线程同时工作,而线程上线数量取决于初始化时指定的最大值。
1.创建一个信号量
创建时初始值不要超过信号量最大限度。
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpAttributes,
LONG lInitialCount,
LONG lMaximumCount,
LPCTSTR lpName
);
***例子:HANDLE HS=CreateSemaphore(NULL,0,2,NULL);***//0:初值 2:最大值
2.获得信号量锁定
因为Semaphore是核心对象,所以可以用WaitForSIngleObject()获得锁定,但一次只能锁定一个。对单个 线程来说,其可以用Wait多次锁定,也可以用Release一次释放多个,但有一点,不要释放超过最大限度。
3.解除信号量锁定
程序获得信号量后应当在结束同步控制时将其释放掉。就像退出临界区一样。
解除信号量锁定时尽量一次释放一个,虽然一次可释放多个,但容易出现不可预料的情况,就像最下面的程序例子。
BOOL ReleaseSemaphore(
HANDLE hSemaphore,
LONG lReleaseCount,
LPLONG lpPreviousCount
);
例:ReleaseSemaphore(HS,1,NULL);
信号量程序实例:现在创建多个线程使用同一信号量,让其打印出1来,观察打印结果,总结规律。程序思路:创建一个信号量,通常其初始值为0,然后释放掉一个信号量,于是Wait函数返回,最先等待的线程将开始运行。在打印完1后释放掉2个信号值,接着会有两个线程开始运行,如细胞分裂,其打印个数将会以2倍速度扩张。但初始信号量最大值被 设定为2个,却有多个(为用户指定个数)打印1,因为这一设定,程序可被 组织成各种各样的同步机制。
代码:
#include<stdio.h>
#include<windows.h>
HANDLE HC1;
DWORD WINAPI FUN1(LPVOID P)
{
while(1)
{
WaitForSingleObject(HC1,INFINITE);
printf("1");
Sleep(1000);
ReleaseSemaphore(HC1,2,NULL);
}
return 0;
}
DWORD WINAPI FUN2(LPVOID P)
{
while(1)
{
printf("\n");
Sleep(990);
}
return 0;
}
int main()
{
int i;
printf("请输入你要同时打印的线程个数:");
scanf("%d",&i);
HC1=CreateSemaphore(NULL,0,2,NULL);
ReleaseSemaphore(HC1,1,NULL);
CreateThread(NULL,0,FUN2,NULL,0,NULL);
while(i--)
{
CreateThread(NULL,0,FUN1,NULL,0,NULL);
}
Sleep(INFINITE);
return 0;
}
运行截图:
分析:申请了10个线程,但信号量最大值为2,一个循环一次申请一个,却释放两个,最终所有线程都有了信号,但却同时最多有10个线程在打印1,所以说ReleaseSemaphore用不好是非常可怕的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)