可警报 I/O
可警报 I/O 是应用程序线程仅在处于可警报状态时处理异步 I/O 请求的方法。
若要了解线程何时处于可警报状态,请考虑以下方案:
- 线程使用指向回调函数的指针调用 ReadFileEx 来启动异步读取请求。
- 线程使用指向回调函数的指针调用 WriteFileEx 来启动异步写入请求。
- 线程调用一个函数,该函数从远程数据库服务器提取一行数据。
在此方案中,对 ReadFileEx 和 WriteFileEx 的调用很可能在步骤 3 中的函数调用之前返回。 这样做时,内核会将指向回调函数的指针放在线程的异步过程调用 (APC) 队列中。 内核专门维护此队列,以保留返回的 I/O 请求数据,直到它可由相应的线程处理。
当行提取完成并且线程从函数返回时,其最高优先级是通过调用回调函数来处理队列中返回的 I/O 请求。 为此,它必须进入可警报状态。 线程只能通过使用相应标志调用以下函数之一来执行此操作:
- SleepEx
- WaitForSingleObjectEx
- WaitForMultipleObjectsEx
- SignalObjectAndWait
- MsgWaitForMultipleObjectsEx
当线程进入可警报状态时,会发生以下事件:
- 内核会检查线程的 APC 队列。 如果队列包含回调函数指针,则内核会从队列中删除指针并将其发送到线程。
- 线程执行回调函数。
- 对队列中剩余的每个指针重复执行步骤 1 和 2。
- 当队列为空时,线程会从将其置于可警报状态的函数中返回。
在此方案中,一旦线程进入可警报状态,它将调用发送到 ReadFileEx 和 WriteFileEx 的回调函数,然后从将其置于可警报状态的函数返回。
如果线程在 APC 队列为空时进入可警报状态,则内核将暂停该线程的执行,直到发生以下情况之一:
- 正在等待的内核对象将发出信号。
- 回调函数指针放置在 APC 队列中。
使用可警报 I/O 的线程处理异步 I/O 请求的效率比只需等待 在 OVERLAPPED 结构中的事件标志上设置时更高效,并且可警报 I/O 机制比使用 I/O 完成端口 更复杂。 但是,可警报 I/O 仅将 I/O 请求的结果返回给启动该请求的线程。 I/O 完成端口没有此限制。
相关主题