CreateMutexW 函数 (synchapi.h)
创建或打开命名或未命名的互斥体对象。
若要为对象指定访问掩码,请使用 CreateMutexEx 函数。
语法
HANDLE CreateMutexW(
[in, optional] LPSECURITY_ATTRIBUTES lpMutexAttributes,
[in] BOOL bInitialOwner,
[in, optional] LPCWSTR 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。 之所以发生这种情况,是因为这些对象共享相同的命名空间。
该名称可以具有“全局”或“本地”前缀,以在全局或会话命名空间中显式创建对象。 名称的其余部分可以包含除反斜杠字符(\)以外的任何字符。 有关详细信息,请参阅 内核对象命名空间。 快速用户切换是使用终端服务会话实现的。 内核对象名称必须遵循终端服务概述的准则,以便应用程序能够支持多个用户。
可以在专用命名空间中创建对象。 有关详细信息,请参阅 对象命名空间。
返回值
如果函数成功,则返回值是新创建的互斥体对象的句柄。
如果函数失败,则返回值 NULL。 若要获取扩展的错误信息,请调用 GetLastError。
如果互斥体是命名互斥体,并且此函数调用之前存在该对象,则返回值是现有对象的句柄,GetLastError 函数返回 ERROR_ALREADY_EXISTS。
言论
CreateMutex 返回的句柄具有 MUTEX_ALL_ACCESS 访问权限;它可用于需要互斥对象句柄的任何函数,前提是调用方已被授予访问权限。 如果从服务或模拟其他用户的线程创建互斥体,则可以在创建互斥表达式时将安全描述符应用到互斥体,或者通过更改其默认 DACL 来更改创建过程的默认安全描述符。 有关详细信息,请参阅 同步对象安全和访问权限。
如果使用命名互斥体将应用程序限制为单个实例,恶意用户可以在执行此操作之前创建此互斥体,并阻止应用程序启动。 为防止这种情况,请创建一个随机命名的互斥体并存储该名称,以便它只能由授权用户获取。 或者,可以将文件用于此目的。 若要将应用程序限制为每个用户的一个实例,请在用户的配置文件目录中创建锁定的文件。
调用进程的任何线程都可以在调用其中一个 等待函数中指定互斥对象句柄。 当发出指定对象的状态发出信号时,单对象等待函数将返回。 可以指示多对象等待函数在发出任何一个或发出所有指定对象的信号时返回。 当等待函数返回时,等待线程将释放以继续执行。
当互斥对象不受任何线程所有时,该对象的状态将发出信号。 创建线程可以使用 bInitialOwner 标志请求互斥体的直接所有权。 否则,线程必须使用其中一个等待函数来请求所有权。 发出互斥体状态信号后,将授予一个等待线程所有权,互斥体的状态更改为非对齐状态,等待函数返回。 在任何给定时间,只有一个线程可以拥有互斥体。 拥有线程使用 ReleaseMutex 函数释放其所有权。
拥有互斥体的线程可以在重复的等待函数调用中指定相同的互斥体,而不会阻止其执行。 通常,不会重复等待相同的互斥体,但此机制可防止线程在等待它已拥有的互斥体时自行死锁。 但是,若要释放其所有权,线程必须在每次互斥体满足等待时调用 ReleaseMutex 一次。
两个或多个进程可以调用 CreateMutex 来创建同一命名的互斥体。 第一个进程实际上创建了互斥体,并且具有足够访问权限的后续进程只需打开现有互斥锁的句柄。 这使多个进程能够获取同一互斥体的句柄,同时减轻用户确保首先启动创建过程的责任。 使用此方法时,应将 bInitialOwner 标志设置为 FALSE;否则,很难确定哪个进程具有初始所有权。
多个进程可以具有同一互斥体对象的句柄,从而允许使用该对象进行进程间同步。 可以使用以下对象共享机制:
- 如果
lpMutexAttribut 参数启用了 CreateMutex 继承,则es CreateProcess 函数创建的子进程可以继承互斥体对象的句柄。 此机制适用于命名和未命名的互斥体。 - 进程可以在调用 DuplicateHandle 函数时指定互斥对象的句柄,以创建可由另一个进程使用的重复句柄。 此机制适用于命名和未命名的互斥体。
- 进程可以在调用 [OpenMutex](./nf-synchapi-openmutexw.md) 或 CreateMutex 函数中指定命名 mutex 来检索互斥对象的句柄。
例子
有关使用 CreateMutex的示例,请参阅 使用互斥体对象。
注意
synchapi.h 标头将 CreateMutex 定义为一个别名,该别名根据 UNICODE 预处理器常量的定义自动选择此函数的 ANSI 或 Unicode 版本。 将中性编码别名与不中性编码的代码混合使用可能会导致编译或运行时错误不匹配。 有关详细信息,请参阅函数原型的
要求
要求 | 价值 |
---|---|
最低支持的客户端 | Windows XP [桌面应用 |UWP 应用] |
支持的最低服务器 | Windows Server 2003 [桌面应用 |UWP 应用] |
目标平台 | 窗户 |
标头 | synchapi.h (包括 Windows Server 2003、Windows Vista、Windows 7、Windows Server 2008 Windows Server 2008 R2 上的 Windows.h) |
库 | Kernel32.lib |
DLL | Kernel32.dll |