OS中的阻塞与非阻塞IO、同步与异步IO
本文最后更新于:3 个月前
前言
IO 指的是用户态的进程,需要操作系统帮助其进行数据的读入和写出。
以 IN 为例,可以分为两个步骤:从磁盘、网络等地方将数据放到内核空间(准备内核数据)、数据从内核空间拷贝到用户空间(内核空间的数据拷贝到用户空间)。
阻塞 I/O
阻塞 I/O 阻塞等待的是两个过程
:准备内核数据 和 内核数据拷贝到用户空间。
用户进程需要数据的时候,调用 read() 函数,然后用户进程阻塞,直到数据拷贝到用户空间。
非阻塞 I/O
非阻塞 I/O 阻塞只等待一个过程
:准备内核数据 和 内核数据拷贝到用户空间。
当发起非阻塞的 IO 之后,如果发现需要的数据在内核中未准备好,那么直接返回,不等待。然后通过不断轮询内核,来查看有没有准备好数据。如果准备好了数据,那么用户进程再阻塞,等待数据从内核空间拷贝到用户空间这一过程。
基于非阻塞的 I/O 多路复用
非阻塞 I/O 存在问题:当数据未准备好的时候,用户进程需要不断地去轮询内核,查看数据准备好了没有。这个不断轮询的过程,导致用户进程没办法做其它的事情。因此引入了 I/O 多路复用技术。
I/O 多路复用技术:内核数据为装备好的时候,用户直接返回,不阻塞,且不轮询。当内核中的数据准备好之后,以事件通知应⽤程序过来拿数据。
同步 I/O
⽆论是阻塞 I/O、还是⾮阻塞 I/O、非阻塞I/O多路复用,都是同步调⽤。
因为它们在read调⽤时,第二个过程-内核将数据从内核空间拷⻉到应⽤程序空间,这个过程都是需要等待的,也就是说这个过程是同步的。
如果内核实现的拷⻉效率不⾼,read调⽤就会在这个同步过程中等待⽐较⻓的时间。
异步 I/O
真正的异步 I/O 是内核数据准备好
和数据从内核态拷⻉到⽤户态
这两个过程都不⽤等待。
发起 aio_read 之后,就⽴即返回,内核⾃动将数据从内核空间拷⻉到应⽤程序空间,这个拷⻉过程同样是异步的,内核⾃动完成的,和前⾯的同步操作不⼀样,应⽤程序并不需要主动发起拷⻉动作。