nginx自旋锁ngx_spinlock分析

2024-01-10 14:18
文章标签 分析 nginx 自旋 spinlock ngx

本文主要是介绍nginx自旋锁ngx_spinlock分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

以前也看过linux内核自旋锁的实现代码,现在工作主要是应用程序开发,对应用程序开发不是太了解,我喜欢通过看优秀的开源软件学习软件开发,之前对linux kernel感兴趣就是看内核代码,现在工作需要http,数据库,网络编程这方面的只是,我想学习http和网络编程看完nginx我想也差不多了。


void ngx_spinlock函数代码:

void
ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin)
{#if (NGX_HAVE_ATOMIC_OPS)ngx_uint_t  i, n;for ( ;; ) {// 没有上锁则上锁,上锁成功则返回  if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {return;}if (ngx_ncpu > 1) {  //SMPfor (n = 1; n < spin; n <<= 1) {for (i = 0; i < n; i++) {ngx_cpu_pause();}if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {return;}}}ngx_sched_yield();  // 看具体实现,任务调度或者usleep。}#else}





最值得研究的在我看来是应该是ngx_atomic_cmp_set函数的实现。下面是这个函数(其实是个宏定义)
的一个实现。
这和linux内核的自旋锁本质是一样的,核心是在锁总线的情况下,原子完成比较和交换操作,也就是mem和newval
的比较和交换操作。如果上锁成功返回值大于O。
    #define LOCK_PREFIX    "lock;"  
    #define __sync_bool_compare_and_swap(mem, oldval, newval) \  
      ({ __typeof (*mem) ret;                             \  
             __asm __volatile (LOCK_PREFIX "cmpxchgl %2, %1;sete %%al; movzbl %%al,%%eax"                \  
                                : "=a" (ret), "=m" (*mem)                  \  
                                : "r" (newval), "m" (*mem), "a" (oldval)\  
                                :"memory");         \  
                                  ret; })  

我用cscope查找 ngx_sched_yield()函数定义,下面是查找结果。我们可以发现这个函数nginx
根据不同情况有三种实现,*nix提供usleep和sched_yield,win32是SwitchToThread()。
win32我不了解,不过看名字就知道什么意思,切换进程。我们说一下*nix的实现。
*** src/os/unix/ngx_process.h:
ngx_sched_yield[71]            #define ngx_sched_yield() sched_yield()
ngx_sched_yield[73]            #define ngx_sched_yield() usleep(1)

*** src/os/win32/ngx_process.h:
ngx_sched_yield[56]            #define ngx_sched_yield() SwitchToThread()
打开ngx_process.h头文件
有下面几行代码。这意思就很清晰了,不多说。
#if (NGX_HAVE_SCHED_YIELD)
#define ngx_sched_yield()  sched_yield()
#else
#define ngx_sched_yield()  usleep(1)
#endif

*nix OS应用层提供的任务调度函数。
#include <sched.h>
sched_yield()

这篇关于nginx自旋锁ngx_spinlock分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/591092

相关文章

Olingo分析和实践之EDM 辅助序列化器详解(最佳实践)

《Olingo分析和实践之EDM辅助序列化器详解(最佳实践)》EDM辅助序列化器是ApacheOlingoOData框架中无需完整EDM模型的智能序列化工具,通过运行时类型推断实现灵活数据转换,适用... 目录概念与定义什么是 EDM 辅助序列化器?核心概念设计目标核心特点1. EDM 信息可选2. 智能类

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1

Olingo分析和实践之ODataImpl详细分析(重要方法详解)

《Olingo分析和实践之ODataImpl详细分析(重要方法详解)》ODataImpl.java是ApacheOlingoOData框架的核心工厂类,负责创建序列化器、反序列化器和处理器等组件,... 目录概述主要职责类结构与继承关系核心功能分析1. 序列化器管理2. 反序列化器管理3. 处理器管理重要方

Nginx安全防护的多种方法

《Nginx安全防护的多种方法》在生产环境中,需要隐藏Nginx的版本号,以避免泄漏Nginx的版本,使攻击者不能针对特定版本进行攻击,下面就来介绍一下Nginx安全防护的方法,感兴趣的可以了解一下... 目录核心安全配置1.编译安装 Nginx2.隐藏版本号3.限制危险请求方法4.请求限制(CC攻击防御)

nginx中端口无权限的问题解决

《nginx中端口无权限的问题解决》当Nginx日志报错bind()to80failed(13:Permissiondenied)时,这通常是由于权限不足导致Nginx无法绑定到80端口,下面就来... 目录一、问题原因分析二、解决方案1. 以 root 权限运行 Nginx(不推荐)2. 为 Nginx

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

解决1093 - You can‘t specify target table报错问题及原因分析

《解决1093-Youcan‘tspecifytargettable报错问题及原因分析》MySQL1093错误因UPDATE/DELETE语句的FROM子句直接引用目标表或嵌套子查询导致,... 目录报js错原因分析具体原因解决办法方法一:使用临时表方法二:使用JOIN方法三:使用EXISTS示例总结报错原

nginx 负载均衡配置及如何解决重复登录问题

《nginx负载均衡配置及如何解决重复登录问题》文章详解Nginx源码安装与Docker部署,介绍四层/七层代理区别及负载均衡策略,通过ip_hash解决重复登录问题,对nginx负载均衡配置及如何... 目录一:源码安装:1.配置编译参数2.编译3.编译安装 二,四层代理和七层代理区别1.二者混合使用举例

nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析(结合应用场景)

《nginx-t、nginx-sstop和nginx-sreload命令的详细解析(结合应用场景)》本文解析Nginx的-t、-sstop、-sreload命令,分别用于配置语法检... 以下是关于 nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析,结合实际应

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串