信号灯对象

信号灯对象 是一个同步对象,用于维护零和指定最大值之间的计数。 每次线程完成信号灯对象的等待时,计数都会递减,每次线程释放信号量时递增。 当计数达到零时,不会再成功等待信号灯对象状态发出信号。 信号灯的状态设置为在信号量大于零时发出信号,当信号量计数为零时不对齐。

信号灯对象可用于控制可支持有限数量的用户的共享资源。 它充当一个入口,用于将共享资源的线程数限制为指定的最大数目。 例如,应用程序可能会对它创建的窗口数施加限制。 它使用最大计数等于窗口限制的信号灯,在创建窗口时递减计数,并在关闭窗口时递增计数。 应用程序指定在创建每个窗口之前调用其中一个 等待函数的信号灯对象。 当计数为零(指示已达到窗口限制)时,等待函数会阻止执行窗口创建代码。

线程使用 CreateSemaphoreCreateSemaphoreEx 函数来创建信号灯对象。 创建线程指定对象的初始计数和最大值。 初始计数不得小于零,也不得大于最大值。 创建线程还可以指定信号灯对象的名称。 其他进程中的线程可以通过在调用 OpenSemaphore 函数中指定其名称来打开现有信号灯对象的句柄。 有关互斥体、事件、信号灯和计时器对象的名称的其他信息,请参阅 进程间同步

如果多个线程正在信号灯上等待,则选择等待线程。 不要假定先入先出(FIFO)顺序。 内核模式 APC 等外部事件可以更改等待顺序。

每次 等待函数之一 返回,因为信号灯的状态设置为信号,信号量计数会减少一个。 ReleaseSemaphore 函数将信号灯的计数增加指定量。 计数永远不能小于零或大于最大值。

信号灯的初始计数通常设置为最大值。 然后,随着受保护资源的消耗,计数将从该级别递减。 或者,可以在初始化应用程序时创建一个信号灯,其初始计数为零,以阻止对受保护资源的访问。 初始化后,可以使用 ReleaseSemaphore 将计数递增为最大值。

拥有互斥对象的线程可以反复等待同一互斥体对象发出信号,而不会阻止其执行。 但是,每次完成等待作时,重复等待同一信号灯对象的线程会递减信号灯的计数;当计数变为零时,线程将被阻止。 同样,只有拥有 mutex 的线程才能成功调用 ReleaseMutex 函数,不过任何线程都可以使用 ReleaseSemaphore 来增加信号灯对象的计数。

线程可以通过重复指定对任何 等待函数调用中的同一信号灯对象,多次递减信号灯的计数。 但是,使用包含同一信号灯的多个句柄的数组调用多个对象等待函数之一不会导致多个递减。

使用信号灯对象后,调用 CloseHandle 函数以关闭句柄。 信号灯对象在最后一个句柄关闭时被销毁。 关闭句柄不会影响信号灯计数;因此,请确保在关闭句柄或进程终止之前调用 ReleaseSemaphore。 否则,挂起的等待作将无限期超时或无限期继续,具体取决于是否已指定超时值。

使用信号灯对象