一、IO模型
一次read操作:
(1)等待数据准备好:从磁盘到内核内存
(2)从内核内存复制到进程内存
示意图如下:
I/O类型:
同步和异步:synchronous,asynchronous
关注的是消息通知机制
同步: 调用发出之后不会立即返回,但一旦返回,则返回的是最终结果
异步: 调用发出之后,被调用方立即返回消息,但返回的并非最终结果;被调用者通过状态、通知机制等来通知调用者,或通过回调函数来处理结果
阻塞和非阻塞: block, nonblock
关注的是调用者等待被调用者返回结果时的状态
阻塞: 调用结果返回之前,调用者会被挂起;调用者只有在得到返回结果之后才能继续
非阻塞: 调用者在结果返回之前,不会被挂起,即调用不会阻塞调用者
I/O模型:
blocking IO: 阻塞式IO
nonblocking IO: 非阻塞式IO
IO multiplexing: 复用型IO
select(),poll()
signal driven IO: 事件驱动式IO
通知:
水平触发: 多次通知
边缘触发: 只通知一次
asynchronous IO: 异步IO
上图为阻塞型IO:调用者发起请求后,整个过程会被挂起,处于不可中断状态,直到IO完成。
上图为非阻塞型IO:调用者发起请求后,内核会立即响应。内核准备数据的第一阶段,调用者虽然不会被阻塞,但是处于"盲等待",调用者会每隔一段时间向内核发起调用,询问是否准备好数据, 拷贝数据的第二阶段,调用者依然是被阻塞的。
上图为复用型IO:简单理解为有一个代理来为调用者服务,这个代理可能是select或者poll,代理接收一个请求之后,可以继续接收下一个请求,调用者被阻塞在select上,到数据复制第二阶段,调用者被阻塞在IO阶段。select默认上限为1024个
上图为事件驱动型IO:调用者发起请求之后,被调用者立即响应请求,然后调用者可以去做别的事情,等到第一阶段完成后,被调用者向调用者发通知,告诉调用者数据已准备好,调用者再去处理第二阶段。事件驱动型IO的好处就是可以一次处理多个请求。
事件型IO第二阶段是被阻塞的,第一阶段被调用者准备好数据后,给调用者发通知的机制有两种:水平触发和边缘触发
水平触发:多次通知,发送通知后没响应,就会一直发送通知直到通知被调用者响应
边缘触发: 通知一次,发送一次通知调用者没响应,那就不会再发通知,调用者没接收到通知没关系,可以根据回调函数来获取资源
上图为异步型IO:调用者发起请求之后,被调用者响应,然后调用者可以去做别的事情,直到被调用者处理完第一阶段和第二阶段后,最后给调用者发个信号。整个过程调用者不会被阻塞,大大提高了性能。