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_create
、epoll_ctl
和 epoll_wait
,以及两个核心数据结构:红黑树和链表。
-
创建 Epoll 实例:
- 通过
epoll_create
创建一个 epoll 实例,该实例在内核中表现为一个eventpoll
对象,包含一个红黑树和一个就绪链表。
- 通过
-
添加监控事件:
- 使用
epoll_ctl
将需要监控的文件描述符注册到 epoll 实例中。这些文件描述符会被存储在红黑树中,以便于快速查找和管理。
- 使用
-
等待事件通知:
- 调用
epoll_wait
等待事件发生。当某个文件描述符就绪时,epoll 会将该文件描述符放入就绪链表中。epoll_wait
会返回就绪文件描述符的数量,并通知应用程序进行处理。
- 调用
Epoll高效之处在于
- 文件数量无上限
- 只有在第一次调用epoll都需要从用户态到内核态,后续调用不像Select那样全部拷贝,而是根据需要拷贝
- 后续文件就绪拷贝到用户态之后无需再次遍历,而是直接能知道哪些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的分享