CreateSemaphoreA 函数 (winbase.h)

创建或打开命名或未命名的信号灯对象。

若要为对象指定访问掩码,请使用 CreateSemaphoreEx 函数。

语法

HANDLE CreateSemaphoreA(
  [in, optional] LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
  [in]           LONG                  lInitialCount,
  [in]           LONG                  lMaximumCount,
  [in, optional] LPCSTR                lpName
);

参数

[in, optional] lpSemaphoreAttributes

指向 SECURITY_ATTRIBUTES 结构的指针。 如果此参数 NULL,则子进程无法继承句柄。

lpSecurityDescriptor 结构成员为新的信号灯指定安全描述符。 如果此参数 NULL,信号灯将获取默认的安全描述符。 信号灯的默认安全描述符中的 ACL 来自创建者的主要或模拟令牌。

[in] lInitialCount

信号灯对象的初始计数。 此值必须大于或等于零,并且小于或等于 lMaximumCount。 信号灯的计数大于零时,信号灯的状态为零,当信号灯为零时表示为非对齐状态。 每当等待函数释放等待信号灯的线程时,计数将减少一个。 通过调用 ReleaseSemaphore 函数来增加指定数量。

[in] lMaximumCount

信号灯对象的最大计数。 此值必须大于零。

[in, optional] lpName

信号灯对象的名称。 名称限制为 MAX_PATH 个字符。 名称比较区分大小写。

如果 lpName 与现有命名信号灯对象的名称匹配,此函数将请求 SEMAPHORE_ALL_ACCESS 访问权限。 在这种情况下,lInitialCountlMaximumCount 参数将被忽略,因为它们已被创建过程设置。 如果 lpSemaphoreAttributes 参数未 NULL,则确定是否可以继承句柄,但忽略其安全描述符成员。

如果 lpNameNULL,则创建信号灯对象时不带名称。

如果 lpName 与现有事件、互斥体、可等待计时器、作业或文件映射对象的名称匹配,则函数将失败,GetLastError 函数返回 ERROR_INVALID_HANDLE。 之所以发生这种情况,是因为这些对象共享相同的命名空间。

该名称可以具有“全局”或“本地”前缀,以在全局或会话命名空间中显式创建对象。 名称的其余部分可以包含除反斜杠字符(\)以外的任何字符。 有关详细信息,请参阅 内核对象命名空间。 快速用户切换是使用终端服务会话实现的。 内核对象名称必须遵循终端服务概述的准则,以便应用程序能够支持多个用户。

可以在专用命名空间中创建对象。 有关详细信息,请参阅 对象命名空间

返回值

如果函数成功,则返回值是信号灯对象的句柄。 如果在函数调用之前存在命名信号灯对象,该函数将返回现有对象的句柄,GetLastError 返回 ERROR_ALREADY_EXISTS

如果函数失败,则返回值 NULL。 若要获取扩展的错误信息,请调用 GetLastError

言论

CreateSemaphore 返回的句柄具有 SEMAPHORE_ALL_ACCESS 访问权限;它可用于需要信号灯对象的句柄的任何函数,前提是调用方已被授予访问权限。 如果信号灯是从服务或模拟其他用户的线程创建的,则可以在创建信号灯时将安全描述符应用到信号灯,或者通过更改其默认 DACL 来更改创建过程的默认安全描述符。 有关详细信息,请参阅 同步对象安全和访问权限

信号灯对象的计数大于零时发出信号,当信号灯对象的计数等于零时不对齐。 lInitialCount 参数指定初始计数。 计数永远不能小于零或大于 lMaximumCount 参数中指定的值。

调用过程的任何线程都可以在调用其中一个 等待函数中指定信号灯对象句柄。 当发出指定对象的状态发出信号时,单对象等待函数将返回。 可以指示多对象等待函数在发出任何一个或发出所有指定对象的信号时返回。 当等待函数返回时,等待线程将释放以继续执行。 每次线程完成等待信号灯对象时,信号灯对象的计数都会递减一个。 线程完成后,它将调用 ReleaseSemaphore 函数,该函数递增信号灯对象的计数。

多个进程可以具有同一信号灯对象的句柄,从而允许使用该对象进行进程间同步。 可以使用以下对象共享机制:

  • 如果启用了 CreateSemaphore 的 lpSemaphoreAttributes 参数,则 CreateProcess 函数创建的子进程可以继承信号灯对象的句柄。
  • 进程可以在调用 DuplicateHandle 函数时指定信号灯对象句柄,以创建可由另一个进程使用的重复句柄。
  • 进程可以在调用 [OpenSemaphore](/windows/win32/api/synchapi/nf-synchapi-opensemaphorew) 或 CreateSemaphore 函数时指定信号灯对象的名称。
使用 CloseHandle 函数关闭句柄。 系统在进程终止时自动关闭句柄。 信号灯对象在最后一个句柄关闭时被销毁。

例子

有关使用 createSemaphore的示例,请参阅 使用信号灯对象

要求

要求 价值
最低支持的客户端 Windows XP [桌面应用 |UWP 应用]
支持的最低服务器 Windows Server 2003 [桌面应用 |UWP 应用]
目标平台 窗户
标头 winbase.h (包括 Windows.h)
Kernel32.lib
DLL Kernel32.dll

另请参阅

CloseHandle

CreateProcess

CreateSemaphoreEx

DuplicateHandle

对象名称

OpenSemaphore

ReleaseSemaphore

SECURITY_ATTRIBUTES

信号灯对象

同步函数