关于ngx_trylock_accept_mutex的一些解释
关于nginx里面accept互斥锁的处理,群里讨论了很多次,很多人都提出了各种问题,比如问到:在ngx_process_events_and_timers中,为什么在释放ngx_accept_mutex之后,不把ngx_accept_mutex_held清零?
if (ngx_accept_mutex_held) {
ngx_shmtx_unlock(&ngx_accept_mutex);
/* 有人说应该加上ngx_accept_mutex_held = 0; */
}
这里我们好好分析一下ngx_trylock_accept_mutex函数,它就能给我们答案:
ngx_int_t
ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
{
if (ngx_shmtx_trylock(&ngx_accept_mutex)) {
if (ngx_enable_accept_events(cycle) == NGX_ERROR) {
ngx_shmtx_unlock(&ngx_accept_mutex);
return NGX_ERROR;
}
ngx_accept_mutex_held = 1;
return NGX_OK;
}
if (ngx_accept_mutex_held) {
if (ngx_disable_accept_events(cycle) == NGX_ERROR) {
return NGX_ERROR;
}
ngx_accept_mutex_held = 0;
}
return NGX_OK;
}
对照这个函数,我们假想一个情景,若此时nginx有两个worker,我们称为A和B。当A执行这个函数,并在调用ngx_shmtx_trylock时成功,这时它将listen fd注册到自己的epoll中(即ngx_enable_accept_events),然后ngx_accept_mutex_held被置1。注意哦,这里ngx_enable_accept_events处理之后就将其置1是为了表达listen fd此时被A进程注册到epoll中了。很显然这个时候B进程由于获取accept锁失败,自然就没有权利accept了。当进程A在处理完accept之后,就会释放accept锁,让B在下一轮竞争中能有机会获取锁来做accept。
if (ngx_accept_mutex_held) {
ngx_shmtx_unlock(&ngx_accept_mutex);
}
接下来B很争气,获得了accept锁,跟当年进程A一样将listen fd加到epoll中,处理过程如出一辙。这个时候我们来看A进程,由于这次在跟B的较量中败北,但是ngx_accept_mutex_held为true,表明之前曾经注册过listen fd。别忘了失败的代价就是要交出listen fd,皇帝的位置现在由B来做,王冠现在不属于你了。由于此时只有B有权将listen fd注册到自己的epoll中,其他的进程(ngx_accept_mutex_held为true的进程)就要将listen fd从自己的epoll中移除(即ngx_disable_accept_events)。
if (ngx_accept_mutex_held) {
if (ngx_disable_accept_events(cycle) == NGX_ERROR) {
return NGX_ERROR;
}
ngx_accept_mutex_held = 0;
}
说到这里大家别混淆了,nginx的epoll是每个进程私有了,可能在有些系统的设计里,epoll是线程(或者进程)共享的。
--------------------- 本文来自 aweth0me 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/brainkick/article/details/9081017?utm_source=copy
关于ngx_trylock_accept_mutex的一些解释相关推荐
- TCP三次握手和四次挥手的解释
基础知识 在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG. 其中,对于我们日常的分析有用的就是前面的五个字段. 它们的含义是: SYN ...
- java 解释型和编译型
编译型语言和解释型语言 编译型语言: 举一个恰当的例子来理解,一本汉语的书,需要翻译成英文的书来帮助外国人理解,一种就是把正本书翻译完,然后给到外国人来阅读,这种方式就相当于编程中的编译型. 解释型: ...
- [翻译]Python中yield的解释
问题: Python中yield关键字的作用是什么?它做了什么? 例如,我想理解以下代码 def node._get_child_candidates(self, distance, min_dist ...
- (康托展开解释)+ NYOJ 139 我排第几个
描述 现在有"abcdefghijkl"12个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的? 输入 第一行有一个整数n(0<n& ...
- 具体解释可变參数列表
可变參数 至少有一个參数 比如:void add(int a,- ){} 例题 模拟printf()函数 #include <stdio.h> #include <stdarg ...
- 状态压缩dp(hdu2662)(我综合了一个人的解释和另一个人的代码)
hoj 2662 大概题意是:有一个n*m的棋盘,在这个棋盘里边放k个旗子,要求每一行每一列都不能存在一对旗子相邻,问最后总共的方案数. 这道题一看状态非常多,就一定是状压.怎么状压呢?这又是个问题. ...
- java具有自动无用内存回收_Java语言程序设计(一)试卷及答案解释
Java语言程序设计(一)试卷及答案解释 本试卷共6页,满分l00分,考试时间l50分钟. 第一部分选择题 一.单项选择题:本大题共l0小题,每小题l分,共10分.在每小题列出的备选项中只有一项是最符 ...
- jquery.datatable能返回数据绑不上_地磁场可以影响人体机能吗?解释有多种,但都不理想...
信鸽辨别方向的能力特别强,即使上海的信鸽带到几千公里放飞,它仍然会飞回上海.路途中就是碰到狂风暴雨,它也不会迷失方向. 为什么它有这么大的辨别方向的本领呢?科学家对信鸽进行研究,做了这样一个有趣的实验 ...
- linux分区通俗讲解,linux硬盘分区基础及设备号的解释
要了解linux分区,需要先明确一下主分区.扩展分区和逻辑分区这三个概念. 分区概念 主分区:一块物理硬盘上可以被独立使用的一部分,一个硬盘最多可以有4个主分区. 扩展分区:为了突破一个物理硬盘只能有 ...
最新文章
- 登陆成功率 99%,云知声携手平安好医生推声纹登录系统
- 干货 | MTCNN实时人脸检测网络详解与代码演示
- C++中的动态内存分配
- 开源库的使用方法以及libjpeg的移植详解
- CCF BDCI 技术需求与技术成果关联度冠军分享
- Kubernetes的三种集群外部访问方式及使用场景说明:NodePort、LoadBalancer和Ingress
- 第六章 定积分的应用 —— 第一节 定积分的元素法
- app启动速度阶段指标
- CodeForces - 1527E Partition Game(dp+线段树)
- hbuilder热更新
- 机械设计说明书_如何做机械设计课程设计?这篇文章总结很详细
- Yii2 Start Process and File Loading
- Better And Better for Mac(Mac手势神器BAB)中文版
- Qt之调用笔记本摄像头录像功能
- yourshelf是什么意思中文_英语shelf的中文是什么意思
- win10截图软件工具
- node 单元测试_如何在Node中模拟对单元测试的请求
- Byte学堂:共享单车数据处理原理及分析方法
- 数据结构实验(严蔚敏版)----栈与队列
- 守护永恒服务器维护,2月24日5点-10点游戏停服维护公告
热门文章
- WPF学习12:基于MVVM Light 制作图形编辑工具(3)
- mvc3部署到mono上面遇到的问题
- 在服务器生成ssl认证
- .net组件开发系列之武术系列 武术招数 控件生命周期与控件事件机制
- 牛客多校6 - Josephus Transform(线段树求k-约瑟夫环+置换群的幂)
- 牛客 - 车辆调度(dfs)
- POJ - 2226 Muddy Fields(最小点覆盖-二分图最大匹配)
- UVa12166 Equilibrium Mobile修改天平(二叉树+dfs)
- TIS教程04-客户端
- js src 变量_Js基础学习笔记(一)