应用程序内存 | Malloc/free/new/delete分配的内存 |
用户缓冲区 | C语言file结构体里的buffer |
内核缓冲区 | Linux的page cache |
同步阻塞IO | 调用时阻塞直到数据读取完成 |
同步非阻塞IO | 调用时直接返回,程序轮询看数据注备好没有 |
IO多路复用 | 阻塞调用,一旦有准备好的fd就返回 |
异步IO | 数据读写都是操作系统去做,完成了之后回调通知应用程序 |
Reactor模式 | 应用程序不断轮询看IO是否就绪 |
Preactor模式 | 操作系统操作读写,完成后回调通知应用程序 |
Select | Fd都存在一个数组里,有fd就绪返回后,需要遍历整个数组找就绪的fd。 | 数组要在内核态和用户态之间传递。监视的fd上限Linux1024 | |
poll | 和select差不多 | 没fd上限 | |
epoll | 设计了一个逻辑上的epfd,把fd数组关联到上面,向内核传递的是这个数字。注册事件epoll_ctl->监听事件epoll_wait,轮询数组,有事件就绪就返回 | LT模式:水平触发。读缓冲区只要不为空就一直触发读事件;写缓冲区有空间就一直触发写事件。 | 写的死循环:写缓冲区写满的概率很小。注册了写事件后没有没有数据要写,会一直触发,因此写完数据要取消写事件。 |
ET模式:边缘触发。读缓冲区从空到非空触发一次;写缓冲区从满到不满触发一次。 | Short read:用户读数据不读完的话,因为只会触发一次,剩下的就读不到了。所以读数据要一次性读完。 |