waitOnAddress 函数 (synchapi.h)

等待指定地址处的值更改。

语法

BOOL WaitOnAddress(
  [in]           volatile VOID *Address,
  [in]           PVOID         CompareAddress,
  [in]           SIZE_T        AddressSize,
  [in, optional] DWORD         dwMilliseconds
);

参数

[in] Address

要等待的地址。 如果 Address 处的值与 CompareAddress 中的值不同,则函数将立即返回。 如果值相同,则函数不会返回,直到同一进程中的另一个线程通过调用 WakeByAddressSingle 或 WakeByAddressAll 或超时时间(以先到者为准)来指示 Address 处的值已更改。

[in] CompareAddress

指向先前在 Address 处观测到的值的位置的指针。 当 Address 的值与 CompareAddress 中的值不同时,函数将返回 。

[in] AddressSize

值的大小(以字节为单位)。 此参数可以是 1、 2、 4或 8。

[in, optional] dwMilliseconds

操作超时前等待的毫秒数。如果此参数为 INFINITE,则线程无限期等待。

返回值

TRUE 如果等待成功,则为 。 如果操作失败,该函数将 FALSE返回 。 如果等待失败,请调用 GetLastError 以获取扩展的错误信息。 具体而言,如果操作超时, GetLastError 将返回 ERROR_TIMEOUT。

注解

Microsoft Store 应用开发人员可能需要通过安装 Windows 软件开发工具包 (Windows SDK) (SDK) 来获取 synchronization.lib 。

线程可以使用 WaitOnAddress 函数来等待特定值从某个不需要的值更改为任何其他值。 WaitOnAddress 比在循环中使用 whileSleep 函数更高效,因为 WaitOnAddress 不会干扰线程计划程序。 WaitOnAddress 也比事件对象更易于使用,因为不需要创建和初始化事件,然后确保它与 值正确同步。 WaitOnAddress 不会受到内存不足的情况的影响,除了可能提前唤醒线程,如下所述。

同一进程中更改线程正在等待的地址处的值的任何线程都应调用 WakeByAddressSingle 来唤醒单个等待线程,或 调用 WakeByAddressAll 来唤醒所有等待的线程。 如果调用 WakeByAddressSingle ,则其他等待线程将继续等待。

注意:WaitOnAddress 保证在收到地址信号时返回,但出于其他原因也允许它返回。 出于此原因, 在 WaitOnAddress 返回后,调用方应将新值与原始不需要的值进行比较,以确认该值实际上已更改。 例如,以下情况可能会导致提前唤醒线程:
  • 内存不足的情况
  • 已放弃对同一地址的上一次唤醒
  • 在已检查的操作系统内部版本上执行代码
 

示例

以下示例演示如何使用 WaitOnAddress。

ULONG g_TargetValue; // global, accessible to all threads
ULONG CapturedValue;
ULONG UndesiredValue;

UndesiredValue = 0;
CapturedValue = g_TargetValue;
while (CapturedValue == UndesiredValue) {
      WaitOnAddress(&g_TargetValue, &UndesiredValue, sizeof(ULONG), INFINITE);
      CapturedValue = g_TargetValue;
}

要求

要求 值
最低受支持的客户端 Windows 8 [桌面应用 |UWP 应用]
最低受支持的服务器 Windows Server 2012 [桌面应用 |UWP 应用]
目标平台 Windows
标头 synchapi.h (包括 Windows.h)
Library Synchronization.lib
DLL API-MS-Win-Core-Synch-l1-2-0.dll

另请参阅

WakeByAddressAll

WakeByAddressSingle

VBS enclave 中可用的 Vertdll API