IO模型及详解io多路复用

IO模型大致可分为四类:同步阻塞IO(Blocking IO)、同步非阻塞 IO(Non-blocking IO)、 IO 多路复用(IO Multiplexing)、 异步 IO(Asynchronous IO)。

java开发层面的IO分为两种面向流(Input/Output Stream)和面向缓冲区(Buffer),面向流则为BIO,面向缓冲区则为NIO(New IO)NIO依赖操作系统底层select/poll/epoll函数。
java中的NIO,所谓非阻塞,意思是通道(channel)的概念,缓冲区(buffer)可在同一通道内读写操作。

什么是 IO 多路复用?指的是一个进程/线程可以同时监视多个文件描述符(一个网络连接,操作系统底层使用一个文件描述符来表示),一旦其中的一个或者多个文件描述符可读或者可写,系统内核就通知该进程/线程。在 Java 应用层面,如何实现对多个文件描述符的监视呢?需要用到一个非常重要的 Java NIO 组件——Selector 选择器。

io多路复用

可以解释为,Reactor设计模式,其运用操作系统 底层select poll epoll模型,用户态进行系统调用(select poll epoll),切换为内核态,内核态监听事件返回给用户态应用系统,返回int为监听的几个连接发生了事件变化。

select

select系统调用有一个重要的参数fd文件描述符,即你要监听哪些文件描述符(连接),文件描述符集合rset用一个bitmap位图表示,位图大小为1024,即最多只能监听1024个客户端连接。
当发起系统调用时,会将rset拷贝到内核态,然后内核态监听有没有数据可以处理,监听的所有文件描述符都没有数据的话会一直阻塞,知道有数据,将有数据的fd索引置一,然后返回给用户态。

操作系统根据中断信号感知哪个文件描述符有数据,而用户态应用通过系统调用select获取哪些文件描述符有数据等待处理。

poll

Poll工作原理与select基本相同,不同的是将位图改成结构体数组,也有资料说链表,没有了最大1024限制,依然有fd集合的拷贝和O(n)的遍历。

epoll

为了解决fd集合拷贝问题,epoll采用用户态与内核态共享epoll_fds集合,当调用epoll_wait系统调用时,内核态会去检查哪些fd有事件,检查完毕后会将共享的epoll_fds集合重排序,将有事件的fd放在前面,并返回有事件的fd个数。
客户端收到返回个数,就不需要全部遍历,而是直接处理fd集合(红黑树)。
1、创建一个epoll, int epoll_create(int size)

2、注册监听函数int epoll_ctl()

3、等待文件描述符int epoll_wait

原文地址:https://www.cnblogs.com/stubborn-dude/p/15242400.html