可警报 I/O

可警报 I/O 是应用程序线程仅在处于可警报状态时处理异步 I/O 请求的方法。

若要了解线程何时处于可警报状态,请考虑以下方案:

  1. 线程使用指向回调函数的指针调用 ReadFileEx 来启动异步读取请求。
  2. 线程使用指向回调函数的指针调用 WriteFileEx 来启动异步写入请求。
  3. 线程调用一个函数,该函数从远程数据库服务器提取一行数据。

在此方案中,对 ReadFileExWriteFileEx 的调用很可能在步骤 3 中的函数调用之前返回。 这样做时,内核会将指向回调函数的指针放在线程的异步过程调用 (APC) 队列中。 内核专门维护此队列,以保留返回的 I/O 请求数据,直到它可由相应的线程处理。

当行提取完成并且线程从函数返回时,其最高优先级是通过调用回调函数来处理队列中返回的 I/O 请求。 为此,它必须进入可警报状态。 线程只能通过使用相应标志调用以下函数之一来执行此操作:

当线程进入可警报状态时,会发生以下事件:

  1. 内核会检查线程的 APC 队列。 如果队列包含回调函数指针,则内核会从队列中删除指针并将其发送到线程。
  2. 线程执行回调函数。
  3. 对队列中剩余的每个指针重复执行步骤 1 和 2。
  4. 当队列为空时,线程会从将其置于可警报状态的函数中返回。

在此方案中,一旦线程进入可警报状态,它将调用发送到 ReadFileExWriteFileEx 的回调函数,然后从将其置于可警报状态的函数返回。

如果线程在 APC 队列为空时进入可警报状态,则内核将暂停该线程的执行,直到发生以下情况之一:

  • 正在等待的内核对象将发出信号。
  • 回调函数指针放置在 APC 队列中。

使用可警报 I/O 的线程处理异步 I/O 请求的效率比只需等待 在 OVERLAPPED 结构中的事件标志上设置时更高效,并且可警报 I/O 机制比使用 I/O 完成端口 更复杂。 但是,可警报 I/O 仅将 I/O 请求的结果返回给启动该请求的线程。 I/O 完成端口没有此限制。

异步过程调用