nginx读写锁的实现逻辑

  我们一般认为nginx是一个多进程单线程的应用服务,虽然nginx在一个worker进程内是没有数据竞争问题的(因为是单线程),但是不免nginx在多个进程间还有一些需要共享的数据,譬如ngx_http_upstream_zone_module模块将peers数据放在了共享内存中供多个worker进程来使用,又譬如ngx_http_limit_conn_module模块将并发连接数限制也放在了共享内存中,诸如此类的,自然会涉及到共享内存访问的互斥锁的问题,本文对nginx实现的互斥锁进行分析,通过分析学习nginx的实现代码,以便将来可以应用到自己的日常应用程序中去。

  nginx的读写锁实现逻辑是通过自旋锁来实现的。

  nginx一共实现了以下几个api函数:

void ngx_rwlock_wlock(ngx_atomic_t *lock);
void ngx_rwlock_rlock(ngx_atomic_t *lock);
void ngx_rwlock_unlock(ngx_atomic_t *lock);
void ngx_rwlock_downgrade(ngx_atomic_t *lock);

  ngx_rwlock_wlock用来加写锁,ngx_rwlock_rlock用来加读锁,ngx_rwlock_unlock用来对加的锁进行释放,ngx_rwlock_downgrade对写锁进行降级为读锁。

  锁变量是ngx_atomic_t类型,对应的就是一个unsigned long的类型。

以下是ngx_rwlock_wlock的实现代码:

void
ngx_rwlock_wlock(ngx_atomic_t *lock)
{ngx_uint_t  i, n;for ( ;; ) {/* 如果*lock的值是0表示现在没有加任何读写锁ngx_atomic_cmp_set比较如果是lock是0,则将其设置为NGX_RWLOCK_WLOCK表示加锁成功,可以返回了*/if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, NGX_RWLOCK_WLOCK)) {return;}if (ngx_ncpu > 1) {/* 对于多cpu的情况需要进行自旋加锁检测 */for (n = 1; n < NGX_RWLOCK_SPIN; n <<= 1) {for (i = 0; i < n; i++) {ngx_cpu_pause();}if (*lock == 0&& ngx_atomic_cmp_set(lock, 0, NGX_RWLOCK_WLOCK)){return;}}}/* 通知os将自己切出,调度到其他进程 */ngx_sched_yield();}
}

以下是ngx_rwlock_rlock的实现代码:


void
ngx_rwlock_rlock(ngx_atomic_t *lock)
{ngx_uint_t         i, n;ngx_atomic_uint_t  readers;for ( ;; ) {readers = *lock;/* 如果*lock的值不是NGX_RWLOCK_WLOCK表示现在没有加写锁,则可以尝试获取读锁,ngx_atomic_cmp_set比较如果是lock和之前保存的readers一致,则将其设置为readers+1,表示加锁成功,可以返回了*/if (readers != NGX_RWLOCK_WLOCK&& ngx_atomic_cmp_set(lock, readers, readers + 1)){return;}if (ngx_ncpu > 1) {/* 对于多cpu的情况需要进行自旋加锁检测 */for (n = 1; n < NGX_RWLOCK_SPIN; n <<= 1) {for (i = 0; i < n; i++) {ngx_cpu_pause();}readers = *lock;if (readers != NGX_RWLOCK_WLOCK&& ngx_atomic_cmp_set(lock, readers, readers + 1)){return;}}}/* 通知os将自己切出,调度到其他进程 */ngx_sched_yield();}
}

以下是ngx_rwlock_unlock的实现代码:

void
ngx_rwlock_unlock(ngx_atomic_t *lock)
{if (*lock == NGX_RWLOCK_WLOCK) {/* 如果是写锁定了,那么将*lock置为0,表示没有加任何锁了*/(void) ngx_atomic_cmp_set(lock, NGX_RWLOCK_WLOCK, 0);} else {/*如果当前是读锁定了,那么只是将*lock-1,表示少了一个读者 */(void) ngx_atomic_fetch_add(lock, -1);}
}

以下是ngx_rwlock_downgrade的实现代码:

void
ngx_rwlock_downgrade(ngx_atomic_t *lock)
{/* 如果当前是加上了写锁的,因为肯定没有读者,将自己变为读者,所以只有1个读者,因此将*lock设置为1*/if (*lock == NGX_RWLOCK_WLOCK) {*lock = 1;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/727207.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pytorch入门实战 P1-实现手写数字识别

目录 一、前期准备&#xff08;环境数据&#xff09; 1、首先查看我们电脑的配置&#xff1b; 2、使用datasets导入MNIST数据集 3、使用dataloader加载数据集 4、数据可视化 二、构建简单的CNN网络 三、训练模型 1、设置超参数 2、编写训练函数 3、编写测试函数 4、…

子事务的应用

子事务的应用 1. 为什么要使用子事务&#xff1f; 为了防止接口执行失败时&#xff0c;导致事务回滚&#xff0c;接口日志记录不到日志表里面&#xff0c;因而将记录日志表的方法写成子事务的方法。 2. 怎么使用子事务&#xff1f; 在方法名后面加上“_RequiresNew”&#xff…

文物藏品信息管理系统的优势

本系统支持一普标准所有管理信息&#xff0c;包括保管信息、基本情况、鉴定信息、考古发掘信息、来源信息、流传经历、损坏记录、移动记录、修复记录、展览信息、著录信息、收藏单位信息等的管理和维护。 能够实现对藏品信息进行动态管理&#xff0c;提供藏品信息管理指标的维护…

《人工智能怎么学》荣获2023年吴文俊人工智能科学技术奖及赠书活动

中国人工智能学会官网&#xff08;www.caai.cn&#xff09;近日正式公布了2023年吴文俊科学技术奖获奖名单&#xff0c;图书《人工智能怎么学》项目被授予2023年吴文俊人工智能科学技术奖科技进步奖&#xff08;科普项目&#xff09;。2023年吴文俊科学技术奖完整获奖名单见htt…

YOLOv8官方仓库更新,添加YOLOv9模型

目录 &#x1f680;&#x1f680;&#x1f680;订阅专栏&#xff0c;更新及时查看不迷路&#x1f680;&#x1f680;&#x1f680; 摘要 PGI&GELAN 代码实现 实验结果 消融实验 可视化 结论 &#x1f680;&#x1f680;&#x1f680;订阅专栏&#xff0c;更新及时查…

PHP接口代码-在线实名认证-身份实名认证

在我国&#xff0c;身份证是证明身份的证件&#xff0c;我们在生活、工作中都会用到。一般入职一个新公司的时候人事部门的工作人员会让入职人员提供身份证&#xff0c;一是帮员工办理社保等业务和员工档案用&#xff0c;另外还可以用来验证身份。现在科技发达&#xff0c;不仅…

开发充电桩APP提高管理效能

随着社会的发展&#xff0c;电动车已经成为城市交通的重要组成部分&#xff0c;用户所下载的充电类的APP也非常大&#xff0c;而充电桩的建设和利用效率成为了一个亟待解决的问题。在这个背景下&#xff0c;物联网技术的应用成为了提高充电桩效能的关键。虎克技术公司在此领域提…

CyberChef加密解密RSA、AES中文乱码问题有效解决办法

一、AES加密 AES的ECB模式加密&#xff0c;秘钥&#xff1a;1234567812345678 加密效果与utf-8本地加密一致 二、AES解密 AES的ECB模式解密&#xff0c;秘钥&#xff1a;1234567812345678 同理RSA加密设置一样

[C语言]——分支和循环(4)

目录 一.随机数生成 1.rand 2.srand 3.time 4.设置随机数的范围 猜数字游戏实现 写⼀个猜数字游戏 游戏要求&#xff1a; &#xff08;1&#xff09;电脑自动生成1~100的随机数 &#xff08;2&#xff09;玩家猜数字&#xff0c;猜数字的过程中&#xff0c;根据猜测数据的⼤…

【notepad++工具使用之】批量加逗号

背景 在使用sql语句in关键字查询时&#xff0c;我们需要把数据用逗号进行隔开&#xff0c;在数据量非常少的时候&#xff08;十几二十个这样&#xff09;&#xff0c;可以手动的去加逗号分隔符&#xff1b; 但是遇到1000个怎么弄呢&#xff1f; 强大的Notepad 批量处理数据时…

百度智能云发布会定档3月21日,新模型ERNIE Speed已悄然上线

正文 百度智能云官微日前宣布&#xff0c;百度智能云千帆产品发布会&#xff08;AI Cloud Day&#xff09;将于2024年3月21日在北京举行&#xff0c;届时将揭晓千帆ModelBuilder 和 AppBuilder 的最新产品进展&#xff0c;并发布系列新模型及开发工具组件。 记者在百度智能云…

最新的前端开发技术(2024年)

关于作者&#xff1a; 还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#xff0…

如何实现数据中心布线变更管理?

前言 随着科技的不断发展&#xff0c;数据中心作为企业的核心基础设施之一&#xff0c;承载着大量重要的业务数据。在数据中心运维过程中&#xff0c;变更管理流程变得尤为重要&#xff0c;它是确保数据中心基础设施稳定运行和保障数据安全的关键环节。变更管理的定义是指在维…

【开源】SpringBoot框架开发快乐贩卖馆管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 搞笑视频模块2.3 视频收藏模块2.4 视频评分模块2.5 视频交易模块2.6 视频好友模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 搞笑视频表3.2.2 视频收藏表3.2.3 视频评分表3.2.4 视频交易表 四、系…

ue WebUI插件下载官方Github方法

首先要先将EPIC账号绑定Github账号 这个网上有很多教程 我就不细说了 绑定以后点击这个链接 https://github.com/tracerinteractive/UnrealEngine 进去后是这样的 点击这里 下滑找到对应版本下载即可 好了就这样 别被割韭菜了

AI自然语言中默认上下文长度4K 几K是什么意思?

环境&#xff1a; 4K 问题描述&#xff1a; AI自然语言中默认上下文长度4K 几K是什么意思&#xff1f; 解决方案&#xff1a; 在自然语言处理中&#xff0c;“k” 表示 “千”&#xff0c;是一种简写方式。当我们说 “4k” 时&#xff0c;实际上指的是 “4,000”。在上下文…

微服务架构 | 实战常见数据

INFDEX 压测参考值&#xff08;180C&#xff09;线程池Qps/Tps 压测参考值&#xff08;180C&#xff09; 时长TPSTPS极限TP性能TP极限并发CPU负载一般接口5min500200050/100ms120ms1->10/3040%缓存接口5min5000200007/20ms10/25ms1->2/440%一般写接口关键写接口 线程池…

3月6日做题总结(C/C++真题)

星光不负赶路人&#xff0c;时光不负追梦人&#xff01;多一份努力&#xff0c;多一份成功的机会&#xff01; 第一题 int a, b, x, i; a 3; b 4; i 3; x a > b ? i : i--; x的值为&#xff08;&#xff09; A---2 B---3 C---4 D---5 正确答案&#xff1a;B 解…

【射频连接器】SMB/SMC 同轴连接器

阻抗为 50 欧姆的 Connex SMB/SMC 超小型同轴连接器适用于 4 GHz &#xff08;SMB&#xff09; 或 10 GHz &#xff08;SMC&#xff09; 的应用。这些连接器通常比 SMA 便宜&#xff0c;主要用于微波电话和其他非国防电信要求的应用。 SMB 连接器具有快速连接/断开卡扣式配接功…

LoadRunner VS RunnerGo:主流性能测试工具对比谁更胜一筹?

LoadRunner作为性能测试工具的开拓者&#xff0c;测试人员应该都听过&#xff0c;可能也用过&#xff0c;相比较后起之秀Jmeter&#xff0c;使用场景更趋于企业级的性能测试&#xff0c;不太适合个人使用。 RunnerGo呢&#xff0c;是一款基于Go语言、国产自研的测试平台。它支…