由于Redis采起了epoll模型,IO多路复用。同步非阻塞。java
介绍epoll以前必需要先介绍下select和poll。明白select和poll的缺点后才能知道为何epoll这么快。web
// select(xx,读文件描述符集合,写文件描述符集合,异常文件描述符集合,超时时间),咱们只须要关注读文件描述符集合,其余NULL不影响,由于有默认值。 select(max+1, &rset, NULL, NULL, NULL)
rset其实就是fds(文件描述符的集合)。而select模型存储fds的方式是采起的bitmap,默认最大1024个。面试
1.select模型每次都直接将rset(也就是fds)所有拷贝到内核态,由于内核态速度比用户空间态快不少。
2.若是没数据的话,select函数会阻塞,若是有数据的话会执行两步
(1)将有数据的那个fd置位(也就是标记一下,表明这个fd有数据)
(2)select函数不在阻塞,将继续往下执行。也就是总体遍历fds,找到有数据的那个fd读取数据作处理。他的fd不能重用,每一次都须要从新建立新的fds且将用户空间态的fds拷贝到内核态。(这个能够看上面while(1)的代码)
redis
// 表明传入了5个pollfd这个结构体,超时时间是5000,poll总体就是围绕他的pollfd这个结构体来展开的 poll(pollfds, 5, 5000)
poll的结构体是为了fd重复利用,不须要每次都拷贝到内核态用的。
revents:置位用的,若是某个fd有数据了,就把这个revents置位为POLLIN编程
epoll的出现就是为了解决poll最后两个缺点的。数组
epoll_create 至关于建立白板
epoll_ctl至关于往白板上写字,写的内容是一个fd、一个events结构体,events结构体跟pollfd的结构体很像。
epoll_ctl执行完后就获得了epfd,epfd就是循环了五个fd-events放里面,每一个fd都有events事件
epoll_wait
用户进程经过调用select/poll/epoll去处理socket请求的时候, select/poll/epoll因为是阻塞的,因此致使用户进程阻塞;而select/poll/epoll处理的socket用的是非阻塞微信
好比三个redis-cli,假设2个redis-cli写入命令,
select:那么select模型是轮询这三个redis-cli的fd,看哪一个fd有消息,有的话读取处理消息。当他下次再写命令的时候还须要从新建立fd,而后复制到内核态而后再遍历所有。
poll:那么poll模型是轮询这三个redis-cli的fd,看哪一个fd有消息,有的话读取处理消息。下次再写入的时候仍是遍历全局fd,看哪一个fd有消息进行处理。省去了每次都建立新的fd且复制的过程。
epoll:epoll就不轮询了,有消息进来后你通知我,我去处理你的消息,那些没消息的fd我无论。并且复制到内核态的过程我采起牛逼的技术让开销达到最小的极致。socket
微信公众号【Java码农社区】
svg