HTML5技术

Linux网络编程“惊群”问题总结 - Ankers Blog(3)

字号+ 作者:H5之家 来源:H5之家 2017-06-24 18:03 我要评论( )

在早期的Linux版本中,内核对于阻塞在epoll_wait的进程,也是采用全部唤醒的机制,所以存在和accept相似的惊群问题。新版本的的解决方案也是只会唤醒等待队列上的第一个进程或线程,所以,新版本Linux部分的解决了e

在早期的Linux版本中,内核对于阻塞在epoll_wait的进程,也是采用全部唤醒的机制,所以存在和accept相似的“惊群”问题。新版本的的解决方案也是只会唤醒等待队列上的第一个进程或线程,所以,新版本Linux 部分的解决了epoll的“惊群”问题。所谓部分的解决,意思就是:对于部分特殊场景,使用epoll机制,已经不存在“惊群”的问题了,但是对于大多数场景,epoll机制仍然存在“惊群”。

epoll存在惊群的场景如下:在worker保持工作的状态下,都会被唤醒,例如在epoll_wait后调用sleep一次。改写woker函数如下:

void worker(int sfd, int efd, struct epoll_event *events, int k) { (1) { int n, i; n = epoll_wait(efd, events, MAXEVENTS, -1); sleep(2); printf(, k); for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events &EPOLLIN))) { fprintf (stderr, ); close (events[i].data.fd); continue; } else if (sfd == events[i].data.fd) { sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof in_addr; infd = accept(sfd, &in_addr, &in_len); if (infd == -1) { printf(, k, strerror(errno)); break; } printf(, k); close(infd); } } } }

测试结果如下所示:

终于看到惊群现象的出现了。

4、解决惊群问题

  Nginx中使用mutex互斥锁解决这个问题,具体措施有使用全局互斥锁,每个子进程在epoll_wait()之前先去申请锁,申请到则继续处理,获取不到则等待,并设置了一个负载均衡的算法(当某一个子进程的任务量达到总设置量的7/8时,则不会再尝试去申请锁)来均衡各个进程的任务量。后面深入学习一下Nginx的惊群处理过程。

5、参考网址

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 如何实现在Windows上运行Linux程序,附示例代码 - q303248153

    如何实现在Windows上运行Linux程序,附示例代码 - q303248153

    2017-05-16 14:00

  • Linux使用Jexus托管Asp.Net Core应用程序 - 玩双截棍的熊猫

    Linux使用Jexus托管Asp.Net Core应用程序 - 玩双截棍的熊猫

    2017-05-15 08:06

  • 使用Visual Studio 2017作为Linux C++开发工具 - 星夜落尘

    使用Visual Studio 2017作为Linux C++开发工具 - 星夜落尘

    2017-03-12 14:01

  • Linux系统(一)文件系统、压缩、打包操作总结 - 张龙豪

    Linux系统(一)文件系统、压缩、打包操作总结 - 张龙豪

    2017-02-23 16:00

网友点评
2