原创

redis网络模型-IO多路复用-epoll


epoll模式是对select和poll的改进,它提供了三个函数:

微信截图_20230213230037

创建epoll结构体

执行epoll_ctl将fd添加到epoll的红黑树中,等待fd就绪

fd就绪后将对应的fd添加到list_head(就绪列表)中,然后执行epoll_wait方法

执行epoll_wait的时候程序会去检查list_head(就绪列表)

用户空间的空数组events是用来接收内核空间就绪列表数据的,当epoll_wait执行完成返回就绪fd数量时会把list_head里的fd数据拷贝到events中这样用户空间就可以知道是那些fd就绪了

微信截图_20230213225850

相比于select,epoll对于要监听的fd只需要把其添加到内核空间的红黑树就行,而且对于添加过的fd不会删掉会一直保留避免了重复添加fd的问题减少了用户空间到内核空间的拷贝(减少了用户态到内核态的转换)

对于内核空间只拷贝就绪fd集合到用户空间使其确保events中的每一个fd都是就绪的,不用像select和poll还需要在遍历一遍找出就绪的fd

总结

select模式存在的三个问题:

  • 能监听的FD最大不超过1024
  • 每次select都需要把所有要监听的FD都拷贝到内核空间
  • 每次都要遍历所有FD来判断就绪状态

poll模式的问题:

  • poll利用链表解决了select中监听FD上限的问题,但依然要遍历所有FD,如果监听较多,性能会下降

epoll模式中如何解决这些问题的?

  1. 基于epoll实例中的红黑树保存要监听的FD,理论上无上限,而且增删改查效率都非常高,性能不会随监听的FD数量增多而下降
  2. 每个FD只需要执行一次epoll_ctl添加到红黑树,以后每次epol_wait无需传递任何参数,无需重复拷贝FD到内核空间
  3. 内核会将就绪的FD直接拷贝到用户空间的指定位置,用户进程无需遍历所有FD就能知道就绪的FD是谁
redis原理
网络模型
  • 作者:陌攻(联系作者)
  • 发表时间:2023-02-16 09:16
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 公众号转载:请在文末添加作者公众号二维码
  • 评论