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 为零,该函数将测试对象的状态并立即返回。 如果 dwMillisecondsINFINITE,则函数的超时间隔永远不会经过。

[in] dwFlags

此参数可使用以下一个或多个值。

有关将这些值用于保持信号的对象的信息,请参阅“备注”部分。

含义
WT_EXECUTEDEFAULT
0x00000000
默认情况下,回调函数将排队到非 I/O 工作线程。
WT_EXECUTEINIOTHREAD
0x00000001
未使用此标志。

Windows Server 2003 和 Windows XP: 回调函数将排队到 I/O 工作线程。 如果应在处于可警报状态等待的线程中执行函数,则应使用此标志。

从 Windows Vista 和 Windows Server 2008 开始删除 I/O 工作线程。

WT_EXECUTEINPERSISTENTTHREAD
0x00000080
回调函数将排队到永不终止的线程。 它不保证每次都使用相同的线程。 此标志应仅用于短任务,否则可能会影响其他等待操作。

如果线程调用使用 APC 的函数,则必须设置此标志。 有关详细信息,请参阅 异步过程调用

请注意,目前没有真正持久的工作线程,但如果有任何挂起的 I/O 请求,则不会终止任何工作线程。

WT_EXECUTEINWAITTHREAD
0x00000004
回调函数由等待线程本身调用。 此标志应仅用于短任务,否则可能会影响其他等待操作。

如果其他某个线程在回调函数尝试获取同一锁时获取独占锁并调用 UnregisterWaitUnregisterWaitEx 函数,则可能会出现死锁。

WT_EXECUTELONGFUNCTION
0x00000010
回调函数可以执行长时间的等待。 此标志可帮助系统决定是否应创建新线程。
WT_EXECUTEONLYONCE
0x00000008
调用回调函数一次后,线程将不再等待句柄。 否则,每次等待操作完成时都会重置计时器,直到取消等待操作。
WT_TRANSFER_IMPERSONATION
0x00000100
回调函数将使用当前访问令牌,无论是进程令牌还是模拟令牌。 如果未指定此标志,则回调函数仅使用进程令牌执行。

Windowsxp: 在 Windows XP SP2 和 Windows Server 2003 之前,不支持此标志。

返回值

如果该函数成功,则返回值为非零值。

如果函数失败,则返回值为零。 若要获取扩展的错误信息,请调用
GetLastError

注解

在需要时自动创建新的等待线程。 等待操作由线程池中的等待线程执行。 当对象的状态发出信号或超时间隔过时,回调例程由工作线程执行。 如果未WT_EXECUTEONLYONCEdwFlags,则每次发出事件信号或经过超时间隔时,都会重置计时器。

等待完成后,必须调用 UnregisterWaitUnregisterWaitEx 函数来取消等待操作。 (必须取消使用 WT_EXECUTEONLYONCE 的等待操作。) 不要从回调函数内对其中任一函数进行阻塞调用。

请注意,不应对传递给 RegisterWaitForSingleObject 的事件对象进行脉冲处理,因为等待线程可能不会检测到事件在重置之前已发出信号。 除非设置了WT_EXECUTEONLYONCE或WT_EXECUTEINWAITTHREAD标志,否则不应注册仍 (发出信号的对象,例如手动重置事件或终止进程) 。 对于其他标志,在重置事件之前,回调函数的调用次数可能过多。

函数修改某些类型的同步对象的状态。 仅针对其信号状态导致满足等待条件的对象进行修改。 例如,信号灯对象的计数将减少 1。

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

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

默认情况下,线程池最多有 500 个线程。 若要提高此限制,请使用 WinNT.h 中定义的 WT_SET_MAX_THREADPOOL_THREAD 宏。

#define WT_SET_MAX_THREADPOOL_THREADS(Flags,Limit) \
    ((Flags)|=(Limit)<<16)

指定 dwFlags 参数时使用此宏。 宏参数是所需的标志,新限制 (最多 (2<<16) -1 线程) 。 但请注意,应用程序可以通过保持较低的工作线程数来提高其性能。

工作项及其调用的所有函数都必须是线程池安全的。 因此,不能从默认回调环境调用需要持久线程(如 RegNotifyChangeKeyValue 函数)的异步调用。 相反,使用 SetThreadpoolThreadMaximumSetThreadpoolThreadMinimum 函数将线程池最大值设置为线程池最小值,或使用 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

另请参阅

同步函数

线程池

UnregisterWait

UnregisterWaitEx

Wait 函数

WaitOrTimerCallback