createMutexA 函数 (synchapi.h)

创建或打开命名的或未命名的互斥体对象。

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

语法

HANDLE CreateMutexA(
  [in, optional] LPSECURITY_ATTRIBUTES lpMutexAttributes,
  [in]           BOOL                  bInitialOwner,
  [in, optional] LPCSTR                lpName
);

参数

[in, optional] lpMutexAttributes

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

结构的 lpSecurityDescriptor 成员为新的互斥体指定安全描述符。 如果 lpMutexAttributesNULL,则互斥体将获取默认的安全描述符。 互斥体的默认安全描述符中的 ACL 来自创建者的主令牌或模拟令牌。 有关详细信息,请参阅 同步对象安全性和访问权限

[in] bInitialOwner

如果此值为 TRUE 并且调用方创建了互斥体,则调用线程获取互斥对象的初始所有权。 否则,调用线程不会获得互斥体的所有权。 若要确定调用方是否创建了互斥体,请参阅返回值部分。

[in, optional] lpName

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

如果 lpName 与现有命名互斥体对象的名称匹配,则此函数请求 MUTEX_ALL_ACCESS 访问权限。 在这种情况下, 将忽略 bInitialOwner 参数,因为创建过程已设置该参数。 如果 lpMutexAttributes 参数不是 NULL,它将确定是否可以继承句柄,但忽略其安全描述符成员。

如果 lpNameNULL,则创建互斥体对象时不带名称。

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

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

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

返回值

如果函数成功,则返回值是新创建的互斥对象的句柄。

如果函数失败,则返回值为 NULL。 要获得更多的错误信息,请调用 GetLastError。

如果互斥体是命名互斥体,并且对象在调用此函数之前就存在,则返回值是现有对象的句柄, 而 GetLastError 函数返回 ERROR_ALREADY_EXISTS

注解

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

如果使用命名互斥体将应用程序限制为单个实例,恶意用户可以先创建此互斥体,然后阻止应用程序启动。 若要防止出现这种情况,请创建一个随机命名的互斥体并存储该名称,以便只能由授权用户获取该名称。 或者,可以将文件用于此目的。 若要将应用程序限制为每个用户一个实例,请在用户的配置文件目录中创建一个锁定的文件。

调用进程的任何线程都可以在调用某个 等待函数时指定互斥对象句柄。 向指定对象的状态发出信号时,单对象等待函数将返回。 当任何一个或所有指定对象都发出信号时,可以指示多对象等待函数返回。 当等待函数返回时,将释放等待线程以继续其执行。

当互斥对象不归任何线程所有时,会发出信号。 创建线程可以使用 bInitialOwner 标志请求互斥锁的即时所有权。 否则,线程必须使用等待函数之一来请求所有权。 当发出互斥体状态信号时,一个等待线程将被授予所有权,互斥体的状态将更改为非对齐状态,等待函数将返回。 在任何给定时间,只有一个线程可以拥有互斥体。 拥有线程使用 ReleaseMutex 函数释放其所有权。

拥有互斥体的线程可以在重复的 wait 函数调用中指定相同的互斥体,而不会阻止其执行。 通常,你不会重复等待相同的互斥体,但此机制可防止线程在等待它已拥有的互斥体时自行死锁。 但是,若要释放其所有权,每次互斥体满足等待时,线程都必须调用 ReleaseMutex 一次。

两个或多个进程可以调用 CreateMutex 来创建同一命名互斥体。 第一个进程实际上创建互斥体,具有足够访问权限的后续进程只需打开现有互斥锁的句柄。 这使多个进程能够获取同一互斥锁的句柄,同时减轻用户确保首先启动创建过程的责任。 使用此方法时,应将 bInitialOwner 标志设置为 FALSE;否则,可能很难确定哪个进程具有初始所有权。

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

  • 如果 CreateMutex 的 lpMutexAttributes 参数已启用 CreateMutex 的继承,则 CreateProcess 函数创建的子进程可以将句柄继承到互对象。 此机制适用于命名和未命名的互斥体。
  • 进程可以在调用 DuplicateHandle 函数时指定互斥对象的句柄,以创建可由另一个进程使用的重复句柄。 此机制适用于命名和未命名的互斥体。
  • 进程可以在调用 [OpenMutex] (./nf-synchapi-openmutexw.md) 或 CreateMutex 时指定命名互斥体,以检索互斥对象句柄。
使用 CloseHandle 函数关闭句柄。 进程终止时,系统会自动关闭句柄。 互斥对象在其最后一个句柄已关闭时被销毁。

示例

有关 CreateMutex 的示例,请参阅使用互斥体对象

注意

synchapi.h 标头将 CreateMutex 定义为别名,该别名根据 UNICODE 预处理器常量的定义自动选择此函数的 ANSI 或 Unicode 版本。 将非特定编码别名的使用与非非特定编码的代码混合使用可能会导致不匹配,从而导致编译或运行时错误。 有关详细信息,请参阅 函数原型的约定

要求

要求
最低受支持的客户端 Windows XP [桌面应用 | UWP 应用]
最低受支持的服务器 Windows Server 2003 [桌面应用 | UWP 应用]
目标平台 Windows
标头 synchapi.h (包括 Windows Server 2003 上的 Windows.h、Windows Vista、Windows 7、Windows Server 2008 Windows Server 2008 R2)
Library Kernel32.lib
DLL Kernel32.dll

另请参阅

CloseHandle

CreateMutexEx

CreateProcess

DuplicateHandle

互斥对象

对象名称

OpenMutex

ReleaseMutex

SECURITY_ATTRIBUTES

同步函数