简要理解
《Epoll 多路复用》
selector(多路复用神器)
ServerSocket(8088) 调用 accept(判断有没有客户端连接过来)
使用selector的话,就会把 accept事件注册到 selector(也就是连接事件)
客户端 => IO流 => selector(IO流事件 读,或写) => ServerSocket
selector 调用的就是 epoll_create。
没有事件,selector 是阻塞的。阻塞调用 epoll_wait。
selector.poll 调用到数据,进行 register注册事件,调用 epoll_ctl 注册。
参数:案例_群聊系统
============================================================================================================
详情概述
多路复用三种:select,poll,epoll
select,poll 它们两个都是基于一种连接轮询机制,他会把所有的连接收集到我们的服务端一个个轮询,有些连接只是建立,连接上来没有发数据,那么会出现空轮询。
select 最大连接数是 1024。
poll能支持的连接数不限。
epoll呢?是基于事件驱动来做我们的多路复用的。
首先呢,会创建,也就是说分配一个内存块,创建一个事件收集器叫 selector。这个事件收集器是干什么的呢?所有的事件都要注册到这里头来。
比方说,我们的Server在启动的时候,就要向selector进行注册,注册一个什么事件,注册一个accept事件。接下来有Client连接到Server,它首先呢,是有我们的这个多路复用器,这个收集器感知到accept事件发生,有accept事件发生,selector它会通知我们的Server来连接了,由Server把这个连接拿到,并且能建立好连接,当Client与Server建立好连接之后,这个Client还会发数据给我们的Server,那么在发的过程中你注意了,一旦建立连接,这个Client会把它的IO事件也注册到selector这个事件收集器里来,注册进来之后,假如Client发了数据过来,触发一个IO事件,另外一个Client也发了数据过来,那么这个时候,selector会返回一个事件的数组,一个集合events,然后呢,由我们的Server把这两个events拿到,拿到Client的数据之后进行处理。这样能听懂吗?基于事件驱动。
如果说客户端连接到服务端,但是呢,他没有发送数据。selector 此时会处于一个阻塞的状态。
等待有没有事件发生,如果有事件发生,马上会返回一个事件的数组集合。
Linux操作系统里头,它提供了相应的函数,比方说我们要创建一个收集器,或者叫多路复用神器,我们会调用操作系统的 epoll_create
这个函数,来声明一个事件收集器的一个内存空间,专门用来存很多事件的,来感知有没有事件发生。
当我们这个池子,这个收集器创建完之后,那么有没有事件来呢?处于一个监听的状态,监听有没有事件过来,它会调用我们的这个操作系统提供的内核提供的epoll_wait
函数,监听有没有事件过来,如果有事件过来的话,这个epoll_wait
从阻塞变成非阻塞,并且返回事件数组回来,哪些事件需要处理。
同时呢?还有一个函数叫epoll_ctl
,这个就更简单了,当我们客户端向selector注册的时候,调用的就是这个接口,操作系统内核提供了这么一个函数,把我们的事件注册进来,然后由我们的函数epoll_wait
进行监听。
这就是epoll三个函数在我们业界用的最多的,不管是Tomcat,nginx,包括NIO,还是Redis,他的多路复用机制都是一样的。
============================================================================================================