惊群现象

风格不统一 提交于 2020-03-03 05:57:30
惊群

所谓惊群即:多个进程/线程同时阻塞等待同一个事件的发生,如果这个事件发生,那么会唤醒所有进程/线程,但是却只有一个进程/线程会对该事件进行处理,那么其他唤醒的进程/线程会继续休眠阻塞,从而造成性能浪费,这种现象即为惊群。

  1. accept惊群
    • 最常见的即,服务器进程在listen后fork出多个子进程来阻塞accept客户端发起连接,当客户端发起连接时,所有子进程将被唤醒,但是实际上只有一个进程可以获取该连接,而其他进程继续阻塞,不过新版的linux已经解决了这个问题,即唤醒最先阻塞的进程来获取该连接
  2. epoll惊群
    • 第一种情况是在fork之前创建epollfd,然后主进程fork多个子进程,每个子进程将listenfd加入到epollfd中,当一个连接到来会触发epoll惊群,多个子进程的epoll会被同时触发。造成惊群,不过新版的epoll已经解决了此问题
    • 第二种情况是主进程创建listenfd,主进程创建多个子进程,同时每个子进程有自己的epollfd,每个子进程将listenfd加入到epollfd中,这样当一个连接到来时,会触发惊群,有待解决。NGINX中使用互斥锁和主动的方式去解决惊群问题解决了该惊群问题
    • nginx解决惊群问题的方法是在每次循环到epoll_wait时,几个子进程竞争互斥锁,获得互斥锁的子进程则将监听fd加到epoll中,没有获得锁的子进程则将监听fd从epoll中取出,当有新连接到来时,子进程accept了新连接后,则解锁,其他子进程可以继续争抢该锁,这样就保证了每次只有一个进程的epoll注册了listenfd,从而不会出现惊群现象。
  3. 线程池惊群
    • 多个线程共用一个锁和一个条件变量,当多个线程因为同一个条件变量阻塞时,如果用pthread_cond_signal通知时会导致惊群,即多个线程被唤醒,但是只有一个线程能够获得该条件,其他线程继续阻塞
    • 解决方法是多个线程共用一个锁,但是每个线程的条件变量各自不同,这样通知时定向通知,从而不会出现惊群

https://blog.csdn.net/second60/article/details/81252106

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!