epoll惊群效应

epoll是Linux高并发IO复用的一种机制,采用红黑树存储文件描述符。在水平触发(LT)模式下,未处理的事件可能导致多个进程被唤醒,产生惊群效应。解决方法包括切换到边缘触发(ET)模式或使用EPOLLONESHOT标志确保每个事件只唤醒一个进程。EPOLLEXCLUSIVE选项可在ET模式下限制唤醒的进程数量,但可能影响性能。
摘要由CSDN通过智能技术生成

epoll惊群效应介绍

epoll通过一颗红黑树来组织所有被epoll_ctl加入到epoll监听列表中的fd,每一个监听的fd在epoll中用epoll item来标识。

每一个文件描述符都有一个等待队列,队列存放epoll entry,epoll entry中设置某个epoll对该文件描述符关心的事件,如果文件描述符上的事件ready了,可以通过epoll注册的回调函数通知到epoll。

epoll需要有一个等待队列给task在epoll_wait时来睡眠等待。epoll还需要有一个ready_list来组织已经ready的就绪fd,以便能够高效通知给进程task,而不需要再去遍历所有的fd。当事件发生后,唤醒文件描述符睡眠队列的epoll entry,调用其回调。

epoll的惊群现象就发生在ep_send_events<向用户态上报就绪事件过程>中:

在epoll LT模式下,如果事件来了,只要还没有处理,epoll都会通知你。epoll_wait在取到事件的时候并不会马上调用accept,此时还在子函数ep_poll中,因为此时事件并没有被处理掉,系统会继续唤醒别的进程来准备处理这个事件,存在多个进程被唤醒处理一个事件,这就是epoll中的惊群效应

“惊群效应”的保证条件有两个:

  1. 在执行ep_send_events_proc<通知用户>的过程中,如果判断当前是LT模式,则将读取到的epi重新放回到epoll的ready list中。

  2. 只要epoll的ready list不为空,就唤醒睡眠在epoll的task队列。

假设有多个进程共用一个epoll,此时来了一个client连接

  1. 进程a的epoll_wait首先被ep_poll_callback唤醒,执行到2时,如果事件还没有被处理,则唤醒进程b;

  2. 进程b在执行ep_scan_ready_list的时候,事件还没有被处理,则唤醒进程c;

  3. 这个过程一直循环到之前唤醒的某个进程将事件取出,然后c进程从ep_item_poll中取不到事件,也就不会再将epi加回到“就绪链表”了,该事件的LT触发结束了。

解决方法

解决该问题的方法比较简单,使不同进程的epoll_wait互斥调用即可,具体如下:

  • 使用边缘触发EPOLLET模式:边缘触发模式下,只有当文件描述符状态发生变化时才会被唤醒,可以有效避免惊群效应。

  • 使用epoll的EPOLLONESHOT事件:EPOLLONESHOT事件可以保证每个文件描述符只被唤醒一次,需要重新注册到epoll中才能再次被触发。

  • 使用EPOLLEXCLUSIVE:使用EPOLLEXCLUSIVE可以保证只有一个进程或线程被唤醒并处理就绪事件,其他等待此事件就绪的进程或线程不会被唤醒,从而避免了惊群效应。(Note:EPOLLEXCLUSIVE只能在ET模式下使用,且对性能具有一定损耗,谨慎使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值