java八股-IO多路复用机制,Select,poll,epoll-Epoll

时间:2024-11-21 19:19:42

int epoll_create(int size)返回的是指示eventpoll的文件描述符
挂载到rb-root上面的不仅是需要监听的fd,更挂载了一个回调函数,如果该fd就绪了,会立刻添加到list-head里面,list-head是已就绪的链表fd。到时候有fd就绪了之后,就是直接链表拷贝到用户态里面,这用户态里面的链表都是就绪的fd,无需像Select和poll似的重新 O ( n ) O(n) O(n)时间遍历,费劲的p爆!!

Epoll 工作原理

Epoll吧Select的功能拆分为3个。
Epoll 的核心是三个 API:epoll_createepoll_ctlepoll_wait,以及两个核心数据结构:红黑树和链表。

  1. 创建 Epoll 实例

    • 通过 epoll_create 创建一个 epoll 实例,该实例在内核中表现为一个 eventpoll 对象,包含一个红黑树和一个就绪链表。
  2. 添加监控事件

    • 使用 epoll_ctl 将需要监控的文件描述符注册到 epoll 实例中。这些文件描述符会被存储在红黑树中,以便于快速查找和管理。
  3. 等待事件通知

    • 调用 epoll_wait 等待事件发生。当某个文件描述符就绪时,epoll 会将该文件描述符放入就绪链表中。epoll_wait 会返回就绪文件描述符的数量,并通知应用程序进行处理。

Epoll高效之处在于

  1. 文件数量无上限
  2. 只有在第一次调用epoll都需要从用户态到内核态,后续调用不像Select那样全部拷贝,而是根据需要拷贝
  3. 后续文件就绪拷贝到用户态之后无需再次遍历,而是直接能知道哪些fd是就绪的,无需挨个遍历数组

Epoll 有两种工作模式:水平触发(LT)和边缘触发(ET):

  • 水平触发(LT):只要文件描述符的状态是就绪的,每次 epoll_wait 调用都会返回该文件描述符。
  • 边缘触发(ET):文件描述符的状态变化时(从不可读变为可读或从不可写变为可写),epoll_wait 只返回一次该文件描述符。

LT是只要没读完,每次都会通知你去读取,容易造成监听fd的各个进程的‘惊群’现象,重复通知,性能下降
ET是读了一次,就只通知1次,剩下的需要再次手动的去通知,能够避免LT的性能下降。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

PPT链接:
通过百度网盘分享的文件:Redis原理篇.pptx
链接:https://pan.baidu.com/s/1TxzMl1n-Mmo1CHbiczz7jw?pwd=9999
提取码:9999
–来自百度网盘超级会员V8的分享