SignalObjectAndWait 函数 (synchapi.h)

向一个对象发出信号,并等待另一个对象作为单个操作。

语法

DWORD SignalObjectAndWait(
  [in] HANDLE hObjectToSignal,
  [in] HANDLE hObjectToWaitOn,
  [in] DWORD  dwMilliseconds,
  [in] BOOL   bAlertable
);

参数

[in] hObjectToSignal

要发出信号的对象的句柄。 此对象可以是信号灯、互斥体或事件。

如果句柄是信号灯,则需要 SEMAPHORE_MODIFY_STATE 访问权限。 如果句柄是事件,则需要 EVENT_MODIFY_STATE 访问权限。 如果句柄是互斥体,并且调用方不拥有互斥体,则函数将失败并 ERROR_NOT_OWNER

[in] hObjectToWaitOn

要等待的对象句柄。 需要 SYNCHRONIZE 访问权限;有关详细信息,请参阅 同步对象安全性和访问权限。 有关可以指定其句柄的对象类型的列表,请参阅“备注”部分。

[in] dwMilliseconds

超时间隔(以毫秒为单位)。 如果间隔已过,即使对象的状态未对齐且没有完成或异步过程调用, (APC) 对象排队,函数也会返回 。 如果 dwMilliseconds 为零,则函数将测试对象的状态,检查排队的完成例程或 APC,并立即返回。 如果 dwMillisecondsINFINITE,则函数的超时间隔永远不会超过。

[in] bAlertable

如果此参数为 TRUE,则当系统将 I/O 完成例程或 APC 函数排队,并且线程调用函数时,函数将返回 。 如果 为 FALSE,则函数不返回,并且线程不调用完成例程或 APC 函数。

当对 APC 进行排队的函数调用已完成时,完成例程将排队。 此函数返回,并且仅当 bAlertableTRUE 且调用线程是排队 APC 的线程时,才会调用完成例程。

返回值

如果函数成功,则返回值指示导致函数返回的事件。 可以是下列值之一。

返回代码/值 说明
WAIT_ABANDONED
0x00000080L
指定的 对象是一个互斥对象,在拥有的线程终止之前,拥有互斥对象对象的线程未释放该互斥对象。 互斥对象的所有权授予调用线程,互斥体设置为非签名。

如果互斥体正在保护永久性状态信息,则应检查它以确保一致性。

WAIT_IO_COMPLETION
0x000000C0L
等待由一个或多个用户模式 异步过程调用 结束, (APC) 排队到线程。
WAIT_OBJECT_0
0x00000000L
指定对象的状态已发出信号。
WAIT_TIMEOUT
0x00000102L
超时间隔已过,并且对象的状态未对齐。
WAIT_FAILED
(DWORD) 0xFFFFFFFF
函数失败。 要获得更多的错误信息,请调用 GetLastError。

注解

与单独的函数调用(如 SetEvent 后跟 WaitForSingleObjectObject)相比,SignalObjectAndWait 函数提供了一种更高效的方式来向一个对象发出信号,然后等待另一个对象。

SignalObjectAndWait 函数可以等待以下对象:

  • 更改通知
  • 控制台输入
  • 事件
  • 内存资源通知
  • Mutex
  • 进程
  • Semaphore
  • 线程
  • 可等待计时器
有关详细信息,请参阅 同步对象

线程可以使用 SignalObjectAndWait 函数来确保工作线程在向对象发出信号之前处于等待状态。 例如,线程和工作线程可以使用句柄事件对象来同步其工作。 线程执行如下代码:

  dwRet = WaitForSingleObject(hEventWorkerDone, INFINITE);
  if( WAIT_OBJECT_0 == dwRet)
    SetEvent(hEventMoreWorkToDo);

工作线程执行如下代码:

  dwRet = SignalObjectAndWait(hEventWorkerDone,
                              hEventMoreWorkToDo,
                              INFINITE, 
                              FALSE);

请注意,“信号”和“等待”不保证作为原子操作执行。 在其他处理器上执行的线程可以在调用 SignalObjectAndWait 的线程开始对第二个对象的等待之前观察第一个对象的信号状态。

在 Windows 7 中使用 SignalObjectAndWaitPulseEvent 时,请格外小心,因为在多个线程之间使用这些 API 可能会导致应用程序死锁。 由 SignalObjectAndWait 发出信号的线程调用 PulseEvent 以向 SignalObjectAndWait 调用的等待对象发出信号。 在某些情况下, SignalObjectAndWait 的调用方无法及时接收等待对象的信号状态,从而导致死锁。

使用直接或间接创建窗口的 wait 函数和代码时请谨慎。 如果线程创建任何窗口,它必须处理消息。 消息广播将发送到系统中的所有窗口。 使用没有超时间隔的等待函数的线程可能会导致系统死锁。 间接创建窗口的两个代码示例是 DDE 和 COM CoInitialize。 因此,如果你有创建窗口的线程,请确保从其他线程调用 SignalObjectAndWait 。 如果这不可行,可以使用 MsgWaitForMultipleObjectsMsgWaitForMultipleObjectsEx,但功能不等效。

若要编译使用此函数的应用程序, 请将_WIN32_WINNT 定义为 0x0400 或更高版本。 有关详细信息,请参阅 使用 Windows 标头

要求

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

另请参阅

MsgWaitForMultipleObjects

MsgWaitForMultipleObjectsEx

同步函数

等待函数