我在 fAlertable 设置为 TRUE 的情况下使用此函数,因为我在我的框架中使用用户警报作为通用线程中断机制。根据该功能的MSDN页面上的评论,
当调用进入警报等待状态并且用户 APC 可用于调度 GetQueuedCompletionStatusEx 的返回值为 TRUE 时,ulEntriesRemoved 非零并且您的 OVERLAPPED_ENTRY 的“包”未触及。因此,如果您确保所有的 OVERLAPPED_ENTRY 都为其 lpOverlapped 成员设置了一个已知的唯一值,那么在调用 API 之前,您可以通过检查 lpOverlapped 的魔力来更轻松地检测删除的条目是 APC 还是 I/O 完成数据包价值。
为什么我需要检查所有的 OVERLAPPED_ENTRY 而不仅仅是第一个?GetQueuedCompletionStatusEx() 不会总是按顺序填充输出数组,因此我应该只检查第一个而不是循环整个数组(或至少到 ulEntriesRemoved)?此外,鉴于此函数同时使多个完成端口条目出列,是否可以保证它永远不会返回警报和一个或多个完成条目?我特别担心这种可能性,因为评论中指出 ulEntriesRemoved 在警报期间将不为零。尽管页面上的评论进一步提到“如果队列中有任何 I/O 完成数据包,用户 APC 将不会被调度。”,
假设系统在对线程和完成端口条目的用户警报的某种混合中排队,然后线程运行 GetQueuedCompletionStatusEx()。从文档中,我无法确定该函数是否使此调用中的所有完成条目出列,然后每次后续调用都会发出一个用户警报(假设没有更多的完成条目排队)。鉴于文档,这似乎是最有可能的情况,但我不想做出可能被证明是错误的假设......