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,并立即返回。 如果 dwMilliseconds 为 INFINITE,则函数的超时间隔永远不会超过。
[in] bAlertable
如果此参数为 TRUE,则当系统将 I/O 完成例程或 APC 函数排队,并且线程调用函数时,函数将返回 。 如果 为 FALSE,则函数不返回,并且线程不调用完成例程或 APC 函数。
当对 APC 进行排队的函数调用已完成时,完成例程将排队。 此函数返回,并且仅当 bAlertable 为 TRUE 且调用线程是排队 APC 的线程时,才会调用完成例程。
返回值
如果函数成功,则返回值指示导致函数返回的事件。 可以是下列值之一。
返回代码/值 | 说明 |
---|---|
|
指定的 对象是一个互斥对象,在拥有的线程终止之前,拥有互斥对象对象的线程未释放该互斥对象。 互斥对象的所有权授予调用线程,互斥体设置为非签名。
如果互斥体正在保护永久性状态信息,则应检查它以确保一致性。 |
|
等待由一个或多个用户模式 异步过程调用 结束, (APC) 排队到线程。 |
|
指定对象的状态已发出信号。 |
|
超时间隔已过,并且对象的状态未对齐。 |
|
函数失败。 要获得更多的错误信息,请调用 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 中使用 SignalObjectAndWait 和 PulseEvent 时,请格外小心,因为在多个线程之间使用这些 API 可能会导致应用程序死锁。 由 SignalObjectAndWait 发出信号的线程调用 PulseEvent 以向 SignalObjectAndWait 调用的等待对象发出信号。 在某些情况下, SignalObjectAndWait 的调用方无法及时接收等待对象的信号状态,从而导致死锁。
使用直接或间接创建窗口的 wait 函数和代码时请谨慎。 如果线程创建任何窗口,它必须处理消息。 消息广播将发送到系统中的所有窗口。 使用没有超时间隔的等待函数的线程可能会导致系统死锁。 间接创建窗口的两个代码示例是 DDE 和 COM CoInitialize。 因此,如果你有创建窗口的线程,请确保从其他线程调用 SignalObjectAndWait 。 如果这不可行,可以使用 MsgWaitForMultipleObjects 或 MsgWaitForMultipleObjectsEx,但功能不等效。
若要编译使用此函数的应用程序, 请将_WIN32_WINNT 定义为 0x0400 或更高版本。 有关详细信息,请参阅 使用 Windows 标头。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows XP [桌面应用 | UWP 应用] |
最低受支持的服务器 | Windows Server 2003 [桌面应用 | UWP 应用] |
目标平台 | Windows |
标头 | synchapi.h (包括 Windows.h) |
Library | Kernel32.lib |
DLL | Kernel32.dll |