信号量内核对象用于对资源进行计数。它们与所有内核对象一样,包含一个使用数量,但是它们也包含另外两个带符号的32位值,一个是最大资源数量,一个是当前可用资源数量。最大资源数量用于标识信标能够控制的资源的最大数量,而当前资源数量则用于标识当前可以使用的资源的数量。
信号量的使用规则如下:
• 如果当前可用资源的数量大于0,则发出信标信号。
• 如果当前可用资源数量是0,则不发出信标信号。
• 系统决不允许当前可用资源的数量为负值。
• 当前可用资源数量决不能大于最大资源数量。
当使用信标时,不要将信号量对象的使用数量与它的当前资源数量混为一谈。
下面的函数用于创建信标内核对象:
lInitialCount参数用于指明开始时(当前)这些资源中有多少可供使用。可设置0到lMaximumCount之间的一个值。
lMaximumCount参数用于告诉系统,应用程序处理的最大资源数量是多少。由于这是个带符号的32位值,因此最多可以拥有2147483647个资源。
通过调用ReleaseSemaphore函数,线程就能够对信标的当前资源数量进行递增:
以一个停车场的运作为例。简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。
在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。
创建信号量:
信号量的使用规则如下:
• 如果当前可用资源的数量大于0,则发出信标信号。
• 如果当前可用资源数量是0,则不发出信标信号。
• 系统决不允许当前可用资源的数量为负值。
• 当前可用资源数量决不能大于最大资源数量。
当使用信标时,不要将信号量对象的使用数量与它的当前资源数量混为一谈。
下面的函数用于创建信标内核对象:
HANDLE CreateSemaphore(
PSECURITY_ATTRIBUTE psa,
LONG lInitialCount,
LONG lMaximumCount,
PCTSTR pszName);
psa参数指定一个SECURITY_ATTRIBUTES结构,或传递零值,该参数定义了信号量的安全特性。
lInitialCount参数用于指明开始时(当前)这些资源中有多少可供使用。可设置0到lMaximumCount之间的一个值。
lMaximumCount参数用于告诉系统,应用程序处理的最大资源数量是多少。由于这是个带符号的32位值,因此最多可以拥有2147483647个资源。
pszName,指定信号量对象的名称。
当然,通过调用OpenSemaphore函数,另一个进程可以获得它自己的进程与现有信标相关的句柄:HANDLE OpenSemaphore(
DWORD fdwAccess,
BOOL bInheritHandle,
PCTSTR pszName);
通过调用ReleaseSemaphore函数,线程就能够对信标的当前资源数量进行递增:
BOOL ReleaseSemaphore(
HANDLE hsem,
LONG lReleaseCount,
PLONG plPreviousCount);
该函数只是将lReleaseCount中的值添加给信标的当前可用资源数量。通常情况下,为lReleaseCount参数传递1,但是,不一定非要传递这个值。该函数也能够在它的*plPreviousCount中返回当前资源数量的原始值。实际上几乎没有应用程序关心这个值,因此可以传递NULL,将它忽略。
以一个停车场的运作为例。简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。
在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。
抽象的来讲,信号量的特性如下:信号量是一个非负整数(车位数),所有通过它的线程/进程(车辆)都会将该整数减一(通过它当然是为了使用资源),当该整数值为零时,所有试图通过它的线程都将处于等待状态。在信号量上我们定义两种操作: Wait(等待) 和 Release(释放)。当一个线程调用Wait操作时,它要么得到资源然后将信号量减一,要么一直等下去(指放入阻塞队列),直到信号量大于等于一时。Release(释放)实际上是在信号量上执行加操作,对应于车辆离开停车场,该操作之所以叫做“释放”是因为释放了由信号量守护的资源。
创建信号量:
HANDLE g_hSemaphore;
g_hSemaphore = CreateSemaphore(NULL, 2, 3, NULL);//当前有2个资源可用,最多有3个资源可用
在线程中使用:
WaitForSingleObject(g_hSemaphore, INFINITE);//等待信号量>0
。。。//资源的使用
ReleaseSemaphore(g_hSemaphore, 1, NULL);//信号量++
使用完成要进行释放:
CloseHandle(g_hSemaphore);