信号量内核对象有点类似于操作系统中的PV操作,用来对资源进行计数。能够控制多个线程操作资源。首先说一下它包含的东西,与其他内核对象一样,信号量包含一个使用计数,两个带符号的32位值,分别代表最大资源数量和当前资源数量。

刚开始对最大资源数量和当前资源数量不是很了解,搞得云里雾里。最大资源数量为创建信号量时指定的最大资源数量,当前资源数量为当前可用的资源数量。

信号量的使用规则如下有:

1>当前资源的数量大于0时,发出信号量信号。等于0时不发出信号量信号

2>当前资源的数量不能为负值。

3>当前资源的数量不能大于最大资源数量。

信号量的使用:

一、创建

HANDLE CreateSemaphore(
  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
  LONG lInitialCount,
  LONG lMaximumCount,
  LPCTSTR lpName
);

Parameters
lpSemaphoreAttributes [in] Set to NULL. lInitialCount [in] Specifies an initial count for the semaphore object. This value must be greater than or equal to zero and less than or equal to lMaximumCount. The state of a semaphore is signaled when its count is greater than zero and nonsignaled when it is zero. The count is decreased by one whenever a wait function releases a thread that was waiting for the semaphore. The count is increased by a specified amount by calling the ReleaseSemaphore function. lMaximumCount [in] Specifies the maximum count for the semaphore object. This value must be greater than zero. lpName [in] Long pointer to a null-terminated string specifying the name of the semaphore object. The name is limited to MAX_PATH characters and can contain any character except the backslash path-separator character (\). Name comparison is case sensitive.

If lpName matches the name of an existing named semaphore object, the lInitialCount and lMaximumCount parameters are ignored because they have already been set during the creation process.

If lpName is NULL, the semaphore object is created without a name.

If lpName semaphore name does not share a name space with events, mutexes, or file-mapping objects.

 

参数lInitialCount表示开始可以使用的资源数量,当该参数为0时,将不会发出信号量信号,因此此时等待该信号量的所有线程都处于等待状态。

参数lMaximumCount表示最大的资源数量,由于该参数是带符号的32位值,因此最多可以拥有2 147 483 647个资源。

二、对信号量的操作

对信号量地操作主要体现在对信号量当前资源数量的操作上。

1、递减当前资源数量的函数

DWORD WaitForSingleObject(
  HANDLE hHandle,
  DWORD dwMilliseconds
);

以及

DWORD WaitForMultipleObjects(
  DWORD nCount, 
  CONST HANDLE* lpHandles, 
  BOOL fWaitAll, 
  DWORD dwMilliseconds 
);

向这些等待函数传递信号量的句柄,它们在内部会检查信号量的当前资源数量,如果当前的资源数量值大于0,则递减信号量当前资源数,反之处于等待状态。

2、递增当前资源数量的函数

BOOL ReleaseSemaphore(
  HANDLE hSemaphore, 
  LONG lReleaseCount, 
  LPLONG lpPreviousCount 
);

参数lReleaseCount表示释放的资源的个数,通常情况下向这个参数传递1。

这样当前资源数量就进行相应的递增操作,当大于0时,将发送通知,等待该信号量的线程就可以调度了。