是否所有异步I / O最终都在轮询中实现?

时间:2013-10-16 04:22:14

标签: asynchronous io

我曾经遇到异步I / O总是有一个回调形式。但最近我发现一些低级实现正在使用轮询样式API。

  1. kqueue
  2. libpq
  3. 这使我认为可能所有(或大多数)异步I / O(任何文件,套接字,机器端口等)最终都以一种轮询方式实现。也许回调表只是高级API的抽象。

    这可能是一个愚蠢的问题,但我不知道大多数异步I / O实际上是如何在低级别实现的。我刚刚使用了系统级通知,当我看到kqueue - 这是系统通知时,它是一种轮询风格!

    我应该如何理解低级别的异步I / O? 如何从低级别轮询系统制作高级别异步通知(如果确实如此)

1 个答案:

答案 0 :(得分:11)

在最低(或至少,最低价值)硬件级别,异步操作在现代操作系统中真正异步

例如,当您从磁盘读取文件时,操作系统会将您对read的调用转换为一系列磁盘操作(寻找位置,读取块X到Y等)。在大多数现代操作系统中,这些命令被写入特殊寄存器或主存储器中的特殊位置,并且磁盘控制器被告知存在待处理的操作。然后操作系统继续关注其业务,当磁盘控制器完成分配给它的所有操作时,它会触发interrupt,导致请求读取的线程从中断处继续拾取。

无论您正在查看什么类型的低级异步操作(磁盘I / O,网络I / O,鼠标和键盘输入等),最终都会有一个调度命令的阶段到硬件,并且直到硬件到达并且通知操作系统已经完成时才执行“回调”,通常是以中断的形式。

这并不是说没有使用轮询实现的某些异步操作。以异步方式实现任何阻塞操作的一种简单(但天真且昂贵)的方法就是产生等待操作完成的线程(可能在紧密循环中轮询),然后在完成时调用回调。但一般来说,OS级别的常见异步操作实际上是异步的。

值得一提的是,仅仅因为API阻塞并不意味着它的轮询:您可以在异步操作上设置阻塞API,在同步操作上设置非阻塞API。例如,在select和kqueues之类的东西中,线程实际上只是进入睡眠状态,直到发生了一些有趣的事情。 “有趣的东西”以中断的形式出现(通常),这表示操作系统应该唤醒相关的线程以继续工作。它并不只是紧紧地坐在那里等待事情发生。

实际上没有办法判断系统是否仅使用其API来使用轮询或“实际”回调(如中断),但是,有异步操作确实支持异步API。