即使经过很多reading我似乎无法理解非阻塞 IO 在操作系统级别实际上是如何工作的。
如果线程是操作系统调度程序的最细粒度的单元,即。任何必须完成的工作都必须使用线程来完成。那么哪个线程实际上以非阻塞模式进行IO?
示例:
Lets say a thread requests the contents of a socket in non-blocking mode, lets say the
open
system call in POSIX.
这基本上意味着线程想要得到通知或者将检查 IO 完成的特定状态。它不等待IO完成。 但我的问题是谁负责 IO?
- 内核是否启动一个线程来等待 IO?如果是这样,它与主线程启动一个子线程并执行相同操作有何不同?
- 大多数线程都映射到内核线程(绿色线程),那么如果非阻塞模式旋转线程,那么最大的优势是什么?我得到的只是我的 main线程没有等待。
- 是否有其他方法可以在不使用线程的情况下完成 IO?例如直接内存访问 (DMA)?我听说它使用硬件中断(不知道如何不涉及线程)。 所有的IO、DMA都是非阻塞的吗?甚至从磁盘读取?
所有这些问题基本上都是相同的:如果 NIO 仅涉及生成线程来进行等待,那么它与异步 IO 有什么不同,如果不是,那么 IO 是如何完成的?
更多信息:There is no Thread
最佳答案
对于简单的低速 I/O 设备(键盘、鼠标、串行端口等),CPU 几乎必须处理每个字节的数据。实现这一目标的秘诀是 hardware interrupts .
当硬件设备需要 CPU 的关注时(例如,因为它已接收到一个字节的数据,并且需要 CPU 在设备能够接收下一个数据之前“读取”该字节),它会发出中断信号到CPU。
CPU通过以下方式处理中断:
- 保存正在执行的任何线程的上下文,
- 可能会提升当前的 privilege level ,然后
- 它有效地调用一个函数——中断处理程序——负责为硬件提供服务。
低速 I/O 设备的典型中断处理程序可能;
- 从寄存器读取一个字节,
- 也许在另一个寄存器中设置一个标志,
- 将字节存储到 circular buffer ,然后
- 返回。
处理程序通过执行特殊的“从中断返回”操作码来“返回”,该操作码恢复被中断的线程的上下文,并恢复之前的特权级别。
对于高速 I/O 设备(例如文件存储设备或网络接口(interface)),除了硬件很可能会 DMA 之外,情况大致相同。在触发中断之前,将整个数据 block 或数据包传入/传出某个物理内存缓冲区。
关于multithreading - 在非阻塞 IO 中——IO 到底是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71621871/