菜鸟nginx源码剖析数据结构篇(十) 自旋锁ngx_spinlock

2024-03-15 03:08

本文主要是介绍菜鸟nginx源码剖析数据结构篇(十) 自旋锁ngx_spinlock,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

分类: Server - 菜鸟nginx源码剖析 15080人阅读 评论(0) 收藏 举报
nginx 源码 自旋锁 spinlock 剖析

目录(?)[+]

 

菜鸟nginx源码剖析数据结构篇(十) 自旋锁ngx_spinlock

 

  • Author:Echo Chen(陈斌)

  • Email:chenb19870707@gmail.com

  • Blog:Blog.csdn.net/chen19870707

  • Date:Nov 11th, 2014

              自旋锁(Spinlock)是一种 Linux 内核中广泛运用的底层同步机制。自旋锁是一种工作于多处理器环境的特殊的锁,在单处理环境中自旋锁的操作被替换为空操作。当某个处理器上的内核执行线程申请自旋锁时,如果锁可用,则获得锁,然后执行临界区操作,最后释放锁;如果锁已被占用,线程并不会转入睡眠状态,而是忙等待该锁,一旦锁被释放,则第一个感知此信息的线程将获得锁。

    1.源代码位置

     

    源文件:http://trac.nginx.org/nginx/browser/nginx/src/core/ngx_spinlock.c

     

    2.相关结构定义

    原子锁结构 ngx_atomic_t:

       1: typedef unsigned long               ngx_atomic_uint_t;
       2: typedef volatile ngx_atomic_uint_t  ngx_atomic_t;

    原子锁值类型 ngx_atomic_int_t:

       1: typedef long                        ngx_atomic_int_t;

    原子的比较和交换,如果lock和old相等,则set写入lock

       1: #define ngx_atomic_cmp_set(lock, old, set)                                    \
       2:     __sync_bool_compare_and_swap(lock, old, set)

    说明:

    bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
           type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...)

    这两个函数是GCC提供原子的比较和交换,如果*ptr == oldval,就将newval写入*ptr。


    进程主动让出执行权,ngx_sched_yeld

       1: #define ngx_sched_yield()  sched_yield()

    3.源代码剖析

       1: void
       2: ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin)
       3: {
       4:  
       5: #if (NGX_HAVE_ATOMIC_OPS)
       6:  
       7:     ngx_uint_t  i, n;
       8:  
       9:  
      10:     for ( ;; ) {
      11:  
      12:         //*lock == 0,没有上锁则上锁,则调用ngx_atomic_cmp_set上锁,设置*lock=value,然后返回 
      13:         if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
      14:             return;
      15:         }
      16:         
      17:         // 多核
      18:         if (ngx_ncpu > 1) {
      19:             
      20:             //如果 spin 为 80,则第一次等待 1 个 ngx_cpu_pause() 操作,然后再次查看锁是否可用。接下来每轮分别等待 2个、4 个、8 个、16 个、32 个、64 个 ngx_cpu_pause() 操作后再试。
      21:               //这中间过程中如果出现锁被释放从而可以使用的情况,则循环会被中止,spinlock 函数会返回值。如果重试仍没有成功,则执行 ngx_sched_yield,然后再重复上面的操作。
      22:             for (n = 1; n < spin; n <<= 1) {
      23:  
      24:                 for (i = 0; i < n; i++) {
      25:                     ngx_cpu_pause();
      26:                 }
      27:                 
      28:                 //检查是否上锁,如果 *lock == 0,则迅速上锁返回
      29:                 if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
      30:                     return;
      31:                 }
      32:             }
      33:         }
      34:         
      35:         //让出CPU执行权
      36:         ngx_sched_yield();
      37:     }
      38:  
      39: #else
      40:  
      41: #if (NGX_THREADS)
      42:  
      43: #error ngx_spinlock() or ngx_atomic_cmp_set() are not defined !
      44:  
      45: #endif
      46:  
      47: #endif
      48:  
      49: }

     

  • 4.参考资料

     

    1.http://blog.csdn.net/poechant/article/details/8062969

    2.《深入理解Nginx》

  •  

  • -Echo Chen

  • Blog.csdn.net/chen19870707

  • -

这篇关于菜鸟nginx源码剖析数据结构篇(十) 自旋锁ngx_spinlock的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各

Nginx指令add_header和proxy_set_header的区别及说明

《Nginx指令add_header和proxy_set_header的区别及说明》:本文主要介绍Nginx指令add_header和proxy_set_header的区别及说明,具有很好的参考价... 目录Nginx指令add_header和proxy_set_header区别如何理解反向代理?proxy

Nginx配置location+rewrite实现隐性域名配置

《Nginx配置location+rewrite实现隐性域名配置》本文主要介绍了Nginx配置location+rewrite实现隐性域名配置,包括基于根目录、条件和反向代理+rewrite配置的隐性... 目录1、配置基于根目录的隐性域名(就是nginx反向代理)2、配置基于条件的隐性域名2.1、基于条件

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

Ubuntu中Nginx虚拟主机设置的项目实践

《Ubuntu中Nginx虚拟主机设置的项目实践》通过配置虚拟主机,可以在同一台服务器上运行多个独立的网站,本文主要介绍了Ubuntu中Nginx虚拟主机设置的项目实践,具有一定的参考价值,感兴趣的可... 目录简介安装 Nginx创建虚拟主机1. 创建网站目录2. 创建默认索引文件3. 配置 Nginx4

Nginx如何进行流量按比例转发

《Nginx如何进行流量按比例转发》Nginx可以借助split_clients指令或通过weight参数以及Lua脚本实现流量按比例转发,下面小编就为大家介绍一下两种方式具体的操作步骤吧... 目录方式一:借助split_clients指令1. 配置split_clients2. 配置后端服务器组3. 配

Nginx实现前端灰度发布

《Nginx实现前端灰度发布》灰度发布是一种重要的策略,它允许我们在不影响所有用户的情况下,逐步推出新功能或更新,通过灰度发布,我们可以测试新版本的稳定性和性能,下面就来介绍一下前端灰度发布的使用,感... 目录前言一、基于权重的流量分配二、基于 Cookie 的分流三、基于请求头的分流四、基于请求参数的分

一文详解Nginx的强缓存和协商缓存

《一文详解Nginx的强缓存和协商缓存》这篇文章主要为大家详细介绍了Nginx中强缓存和协商缓存的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、强缓存(Strong Cache)1. 定义2. 响应头3. Nginx 配置示例4. 行为5. 适用场景二、协商缓存(协