12

我一直认为异步 I/O 总是有回调形式。但最近我发现一些低级实现正在使用轮询式 API。

  1. 队列

这让我想到,也许所有(或大部分)异步 I/O(文件、套接字、mach-port 等中的任何一个)最终都是以一种轮询方式实现的。也许回调形式只是对更高级别 API 的抽象。

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

我应该如何理解底层的异步 I/O?低级轮询系统如何进行高级异步通知?(如果确实如此)

4

1 回答 1

14

在最低(或至少是最值得关注的)硬件级别,异步操作在现代操作系统中确实是异步的。

例如,当您从磁盘读取文件时,操作系统会将您的调用转换read为一系列磁盘操作(查找位置、读取块 X 到 Y 等)。在大多数现代操作系统上,这些命令要么写入特殊寄存器,要么写入主存储器中的特殊位置,并且通知磁盘控制器有待处理的操作。然后操作系统继续它的业务,当磁盘控制器完成分配给它的所有操作时,它会触发一个中断,导致请求读取的线程从它停止的地方开始。

无论您正在查看哪种类型的低级异步操作(磁盘 I/O、网络 I/O、鼠标和键盘输入等),最终都会有某个阶段将命令分派到硬件,并且“回调”在硬件伸出并通知操作系统它已经完成之前不会执行,通常以中断的形式。

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

还值得一提的是,API 阻塞并不意味着它是轮询:您可以将阻塞 API 放在异步操作上,将非阻塞 API 放在同步操作上。例如,对于和 kqueue 之类的东西select,线程实际上只是进入睡眠状态,直到发生有趣的事情。那个“有趣的东西”(通常)以中断的形式出现,这表明操作系统应该唤醒相关线程以继续工作。它不只是在一个紧密的循环中等待某事发生。

确实无法仅从其 API 判断系统是使用轮询还是“真实”回调(如中断),但是确实存在真正由异步操作支持的异步 API。

于 2013-10-16T04:45:41.110 回答