我曾经遇到异步I / O总是有一个回调形式。但最近我发现一些低级实现正在使用轮询样式API。
答案 0 :(得分:11)
在最低(或至少,最低价值)硬件级别,异步操作在现代操作系统中真正异步。
例如,当您从磁盘读取文件时,操作系统会将您对read
的调用转换为一系列磁盘操作(寻找位置,读取块X到Y等)。在大多数现代操作系统中,这些命令被写入特殊寄存器或主存储器中的特殊位置,并且磁盘控制器被告知存在待处理的操作。然后操作系统继续关注其业务,当磁盘控制器完成分配给它的所有操作时,它会触发interrupt,导致请求读取的线程从中断处继续拾取。
无论您正在查看什么类型的低级异步操作(磁盘I / O,网络I / O,鼠标和键盘输入等),最终都会有一个调度命令的阶段到硬件,并且直到硬件到达并且通知操作系统已经完成时才执行“回调”,通常是以中断的形式。
这并不是说没有使用轮询实现的某些异步操作。以异步方式实现任何阻塞操作的一种简单(但天真且昂贵)的方法就是产生等待操作完成的线程(可能在紧密循环中轮询),然后在完成时调用回调。但一般来说,OS级别的常见异步操作实际上是异步的。
值得一提的是,仅仅因为API阻塞并不意味着它的轮询:您可以在异步操作上设置阻塞API,在同步操作上设置非阻塞API。例如,在select
和kqueues之类的东西中,线程实际上只是进入睡眠状态,直到发生了一些有趣的事情。 “有趣的东西”以中断的形式出现(通常),这表示操作系统应该唤醒相关的线程以继续工作。它并不只是紧紧地坐在那里等待事情发生。
实际上没有办法判断系统是否仅使用其API来使用轮询或“实际”回调(如中断),但是,有异步操作确实支持异步API。