epoll惊群原因分析
- 在主线程中创建一个socket、绑定到本地端口并监听
- 在主线程中创建一个epoll实例(epoll_create(2))
- 将监听socket添加到epoll中(epoll_ctl(2))
- 创建多个子线程,每个子线程都共享步骤2里创建的同一个epoll文件描述符,然后调用epoll_wait(2)等待事件到来accept(2)
- 请求到来,新连接建立
这里的问题就是,在第5步的时候,会有多少个线程被唤醒而从epoll_wait()调用返回?答案是不一定,可能只有一个,也可能有部分,也可能是全部。当然在多个线程都唤醒的情况下,只会有一个线程accept()调用会成功。
为何如此?从内核代码分析,原因如下:
static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
int nr_exclusive, int wake_flags, void *key)
{
wait_queue_t *curr, *next; list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
unsigned flags = curr->flags; if (curr->func(curr, mode, wake_flags, key) &&
(flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
break;
}
}
因为__wake_up_common()的调用是从wake_up_locked()开始的,__wake_up_common的各个参数值为:
- q: struct eventpoll.wq
- mode: TASK_NORMAL
- nr_exclusive:1
- wake_flags: 0
- key:NULL。
- curr->flags: WQ_FLAG_EXCLUSIVE
- curr->func: default_wake_function
if (!list_empty(&ep->rdllist)) {
/*
* Wake up (if active) both the eventpoll wait list and
* the ->poll() wait list (delayed after we release the lock).
*/
if (waitqueue_active(&ep->wq))
wake_up_locked(&ep->wq);
if (waitqueue_active(&ep->poll_wait))
pwake++;
}
if (epi->event.events & EPOLLONESHOT)
epi->event.events &= EP_PRIVATE_BITS;
else if (!(epi->event.events & EPOLLET)) {
/*
* If this file has been added with Level
* Trigger mode, we need to insert back inside
* the ready list, so that the next call to
* epoll_wait() will check again the events
* availability. At this point, no one can insert
* into ep->rdllist besides us. The epoll_ctl()
* callers are locked out by
* ep_scan_ready_list() holding "mtx" and the
* poll callback will queue them in ep->ovflist.
*/
list_add_tail(&epi->rdllink, &ep->rdllist);
ep_pm_stay_awake(epi);
}
epoll惊群原因分析的更多相关文章
- accept与epoll惊群 转载
今天打开 OneNote,发现里面躺着一篇很久以前写的笔记,现在将它贴出来. 1. 什么叫惊群现象 首先,我们看看维基百科对惊群的定义: The thundering herd problem occ ...
- epoll 惊群处理
#include <sys/types.h> #include <sys/socket.h> #include <sys/epoll.h> #include < ...
- 源码剖析Linux epoll实现机制及Linux上惊群
转载:https://blog.csdn.net/tgxallen/article/details/78086360 看源码是对一个技术认识最直接且最有效的方式了,之前用Linux Epoll做过一个 ...
- nginx&http 第三章 惊群
惊群:概念就不解释了. 直接说正题:惊群问题一般出现在那些web服务器上,Linux系统有个经典的accept惊群问题,这个问题现在已经在内核曾经得以解决,具体来讲就是当有新的连接进入到accept队 ...
- Linux惊群效应详解
Linux惊群效应详解(最详细的了吧) linux惊群效应 详细的介绍什么是惊群,惊群在线程和进程中的具体表现,惊群的系统消耗和惊群的处理方法. 1.惊群效应是什么? 惊群效应也有人 ...
- Spark集群无法停止的原因分析和解决
今天想停止spark集群,发现执行stop-all.sh的时候spark的相关进程都无法停止.提示: no org.apache.spark.deploy.master.Master to stop ...
- NGINX怎样处理惊群的
写在前面 写NGINX系列的随笔,一来总结学到的东西,二来记录下疑惑的地方,在接下来的学习过程中去解决疑惑. 也希望同样对NGINX感兴趣的朋友能够解答我的疑惑,或者共同探讨研究. 整个NGINX系列 ...
- Linux网络编程“惊群”问题总结
1.前言 我从事Linux系统下网络开发将近4年了,经常还是遇到一些问题,只是知其然而不知其所以然,有时候和其他人交流,搞得非常尴尬.如今计算机都是多核了,网络编程框架也逐步丰富多了,我所知道的有多进 ...
- epoll(2) 源码分析
epoll(2) 源码分析 文本内核代码取自 5.0.18 版本,和上一篇文章中的版本不同是因为另一个电脑出了问题,但是总体差异不大. 引子留下的问题 关键数据结构 提供的系统调用 就绪事件相关逻辑 ...
随机推荐
- nagios系列(五)之nagios图形显示的配置及自定义插件检测密码是否修改详解
nagios图形显示的配置 在服务端安装相关软件 #1.图形显示管理的依赖库 yum install cairo pango zlib zlib-devel freetype freetype-dev ...
- iOS8中 UILocalNotification 和 UIRemoteNotification 使用注意
先说一个关于UILocalNotification的知识点,容易被忘记: Each app on a device is limited to 64 scheduled local notificat ...
- 解析神奇的 Object.defineProperty
这个方法了不起啊..vue.js是通过它实现双向绑定的..而且Object.observe也被草案发起人撤回了..所以defineProperty更有必要了解一下了. 几行代码看他怎么用 var a= ...
- css怎么让页面上的内容不能被选中
body{ -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-se ...
- php三种无限分类
无限分类,是指从一个最高分类开始,每个子分类都可以分出自己的若干个子分类,可以一直分下去,称为无限级分类: 下面是对省市县的无限极分类的列子.数据库如图: 代码示例如下: /** * @Descrip ...
- Java容器---字符容器StringBuffer & StringBuilder
1.字符串对象 (1)定义 ---String 字符串常量,是不可改变的量,也就是创建后就不能在修改了: --- StringBuffer 字符串变量(线程安全),StringBuffer对象的值都是 ...
- TCP连接的3次握手和4次挥手
TCP连接的3次握手和4次挥手笔记 三次握手 TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确 ...
- MySQL5.7的新特性
MySQL 5.7版本据说已经在了很大的性能提升以及做得更加安全了,想了解更多MySQL 5.7的新特性可以参考我转载叶金荣老师的MySQL 5.7的新特性说明.这里我简单演示一下MySQL 5.7的 ...
- Mac 下 Redis 5.0 的卸载与安装
卸载 停止 redis 服务器 redis-cli shutdown 检测 #检测后台进程是否存在 ps -ef |grep redis #检测6379端口是否在监听 netstat -lntp | ...
- PR2017添加字幕文本或文字水印
1.新建一个文本图层(先点击下右下方区域,避免新建图层是灰色不可用) 2.可以看到已经新建了一个文本图层,然后可以在效果控件修改属性,可以用文字工具在文字的地方进行修改文本.(注意点击T图标才能编辑文 ...