RegisterWaitForSingleObject 函数 (winbase.h)
指示 线程池 中的等待线程等待对象。 发生以下情况之一时,等待线程会将指定的回调函数排队到线程池:
- 指定的对象处于信号状态。
- 超时间隔已过。
语法
BOOL RegisterWaitForSingleObject(
[out] PHANDLE phNewWaitObject,
[in] HANDLE hObject,
[in] WAITORTIMERCALLBACK Callback,
[in, optional] PVOID Context,
[in] ULONG dwMilliseconds,
[in] ULONG dwFlags
);
参数
[out] phNewWaitObject
指向返回时接收等待句柄的变量的指针。 请注意,不能在需要对象句柄的函数(如 CloseHandle)中使用等待句柄。
[in] hObject
对象的句柄。 有关可以指定其句柄的对象类型的列表,请参阅以下“备注”部分。
如果在等待仍处于挂起状态时关闭此句柄,则函数的行为未定义。
句柄必须具有 SYNCHRONIZE 访问权限。 有关详细信息,请参阅 标准访问权限。
[in] Callback
指向应用程序定义的 WAITORTIMERCALLBACK 类型的函数的指针,该函数将在 hObject 处于信号状态或 经过 dwMilliseconds 时执行。 有关详细信息,请参阅 WaitOrTimerCallback。
[in, optional] Context
传递给回调函数的单个值。
[in] dwMilliseconds
超时间隔(以毫秒为单位)。 如果间隔已过,则函数返回 ,即使对象的状态未签名也是如此。 如果 dwMilliseconds 为零,该函数将测试对象的状态并立即返回。 如果 dwMilliseconds 为 INFINITE,则函数的超时间隔永远不会经过。
[in] dwFlags
此参数可使用以下一个或多个值。
有关将这些值用于保持信号的对象的信息,请参阅“备注”部分。
值 | 含义 |
---|---|
|
默认情况下,回调函数将排队到非 I/O 工作线程。 |
|
未使用此标志。
Windows Server 2003 和 Windows XP: 回调函数将排队到 I/O 工作线程。 如果应在处于可警报状态等待的线程中执行函数,则应使用此标志。 从 Windows Vista 和 Windows Server 2008 开始删除 I/O 工作线程。 |
|
回调函数将排队到永不终止的线程。 它不保证每次都使用相同的线程。 此标志应仅用于短任务,否则可能会影响其他等待操作。
如果线程调用使用 APC 的函数,则必须设置此标志。 有关详细信息,请参阅 异步过程调用。 请注意,目前没有真正持久的工作线程,但如果有任何挂起的 I/O 请求,则不会终止任何工作线程。 |
|
回调函数由等待线程本身调用。 此标志应仅用于短任务,否则可能会影响其他等待操作。
如果其他某个线程在回调函数尝试获取同一锁时获取独占锁并调用 UnregisterWait 或 UnregisterWaitEx 函数,则可能会出现死锁。 |
|
回调函数可以执行长时间的等待。 此标志可帮助系统决定是否应创建新线程。 |
|
调用回调函数一次后,线程将不再等待句柄。 否则,每次等待操作完成时都会重置计时器,直到取消等待操作。 |
|
回调函数将使用当前访问令牌,无论是进程令牌还是模拟令牌。 如果未指定此标志,则回调函数仅使用进程令牌执行。
Windowsxp: 在 Windows XP SP2 和 Windows Server 2003 之前,不支持此标志。 |
返回值
如果该函数成功,则返回值为非零值。
如果函数失败,则返回值为零。 若要获取扩展的错误信息,请调用
GetLastError。
注解
在需要时自动创建新的等待线程。 等待操作由线程池中的等待线程执行。 当对象的状态发出信号或超时间隔过时,回调例程由工作线程执行。 如果未WT_EXECUTEONLYONCEdwFlags,则每次发出事件信号或经过超时间隔时,都会重置计时器。
等待完成后,必须调用 UnregisterWait 或 UnregisterWaitEx 函数来取消等待操作。 (必须取消使用 WT_EXECUTEONLYONCE 的等待操作。) 不要从回调函数内对其中任一函数进行阻塞调用。
请注意,不应对传递给 RegisterWaitForSingleObject 的事件对象进行脉冲处理,因为等待线程可能不会检测到事件在重置之前已发出信号。 除非设置了WT_EXECUTEONLYONCE或WT_EXECUTEINWAITTHREAD标志,否则不应注册仍 (发出信号的对象,例如手动重置事件或终止进程) 。 对于其他标志,在重置事件之前,回调函数的调用次数可能过多。
函数修改某些类型的同步对象的状态。 仅针对其信号状态导致满足等待条件的对象进行修改。 例如,信号灯对象的计数将减少 1。
RegisterWaitForSingleObject 函数可以等待以下对象:
- 更改通知
- 控制台输入
- 事件
- 内存资源通知
- Mutex
- 进程
- Semaphore
- 线程
- 可等待计时器
默认情况下,线程池最多有 500 个线程。 若要提高此限制,请使用 WinNT.h 中定义的 WT_SET_MAX_THREADPOOL_THREAD 宏。
#define WT_SET_MAX_THREADPOOL_THREADS(Flags,Limit) \
((Flags)|=(Limit)<<16)
指定 dwFlags 参数时使用此宏。 宏参数是所需的标志,新限制 (最多 (2<<16) -1 线程) 。 但请注意,应用程序可以通过保持较低的工作线程数来提高其性能。
工作项及其调用的所有函数都必须是线程池安全的。 因此,不能从默认回调环境调用需要持久线程(如 RegNotifyChangeKeyValue 函数)的异步调用。 相反,使用 SetThreadpoolThreadMaximum 和 SetThreadpoolThreadMinimum 函数将线程池最大值设置为线程池最小值,或使用 CreateThread 函数创建自己的线程。 (对于原始线程池 API,请使用 QueueUserWorkItem function 指定WT_EXECUTEINPERSISTENTTHREAD。)
若要编译使用此函数的应用程序, 请将_WIN32_WINNT 定义为 0x0500 或更高版本。 有关详细信息,请参阅 使用 Windows 标头。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows XP [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2003 [仅限桌面应用] |
目标平台 | Windows |
标头 | winbase.h (包括 Windows.h) |
Library | Kernel32.lib |
DLL | Kernel32.dll |