惊群问题及解决

1.什么是惊群?

当多个进程/线程同时等待同一个socket的事件,当事件发生时,多个进程/线程同时被唤醒,但只有一个进程/线程响应处理该事件,其余被唤醒的进程/线程从新休眠,这种状况称为惊群。linux

因为唤醒进程须要内核从新调度,因此那些没有响应处理事件的进程也被唤醒就意味着性能浪费,因此须要采起措施避免惊群发生。socket

须要说明的是,对于accept()函数,Linux2.6已经从内核层面解决了惊群问题,作法是当链接来到后,只唤醒等待队列中的第一个进程或线程。函数

2.什么状况下还会有这个问题?

当使用select,poll,epoll时,仍然会有惊群问题。性能

特别须要注意的是,即使是2.6之后的linux,epoll_wait在某些场景下不会出现惊群问题,但其仍旧有很大可能会在另外的场景中出现惊群问题。线程

例如,当epoll_wait以后又sleep的状况,由于信号将唤醒sleep,再也不是内核唤醒等待队列中的第一个进程。server

3.如何解决?

(1)在accept以前加锁,像Nginx那样;
lock;
accept();
unlock;队列

(2)在linux kernel 3.9以后利用SO_REUSEPORT,将socket属性加多一个SO_REUSEPORT
fcntl(serverFd,F_SETFL,flags | O_NONBLOCK |SO_REUSEPORT)进程

相关文章
相关标签/搜索