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

Eon*_*nil 10 io asynchronous

虽然异步I/O总是有一个回调形式,但我一直都是这样.但最近我发现一些低级实现正在使用轮询样式API.

  1. kqueue的
  2. libpq的

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

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

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

Mat*_*ude 12

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

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

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

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

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

实际上没有办法判断系统是否仅使用其API来使用轮询或"实际"回调(如中断),但是,有异步操作可以真正支持异步API.