码迷,mamicode.com
首页 > 其他好文 > 详细

epoll_wait惊群问题

时间:2017-11-07 00:19:03      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:inux   connect   事件   socket   linux   无法   效果   poll   效率   

项目接入层用的模型是,主线程创建listenfd,传入6个子线程,每个子线程一个事件循环,epoll_wait这个listenfd。

如果是listenfd,则epoll_wait返回调用accept,其它fd则另外处理。

这里有个epoll_wait的惊群现象:

当一个新连接到达(connect),所有等待在此listenfd上的线程均会被唤醒,进入到事件处理循环中去,但只有一个循环中的accept()会返回,其它线程均返回-1,并置EAGAIN (11)的errno;

Linux在内核层解决了accept的惊群问题,即accept在同一listenfd上的多个线程,事件到达时只有一个会被唤醒。

但Linux为什么不在内核解决epoll_wait的惊群问题呢?

因为对于listenfd,有确切的语义,只会调用accept。但epoll_wait可以等待listenfd和socketfd及其它多种事件,像socketfd可能存在由多个线程同时去读的情景(只是举例,一般网络编程也无这种场景应用);Linux内核无法加以区分。

————

如何解决epoll_wait的惊群问题?

参考Nginx的方案,使用一个accept_mutex锁,同一时刻listenfd只会加入到其中一个线程的事件循环中监听;当前进程处理的连接达到一定规模后,释放掉mutex,即不再处理新的连接请求。这样其它低负载的线程会拿到锁,去监听;这样也达到一个负载均衡的效果;

————

惊群带来的效率损失,主要在频繁的唤起epoll_wait,带来的系统调用开销。我们目前的处理方式为:

大量TCP长连接,不存在惊群引入的效率问题,因此未处理;只在accept返回-1,errno == 11时,作continue处理;

epoll_wait惊群问题

标签:inux   connect   事件   socket   linux   无法   效果   poll   效率   

原文地址:http://www.cnblogs.com/gm-201705/p/7795654.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!