菜鸟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》

菜鸟nginx源码剖析数据结构篇(十) 自旋锁ngx_spinlock[转]的更多相关文章

  1. 菜鸟nginx源码剖析数据结构篇(十一) 共享内存ngx_shm_t[转]

    菜鸟nginx源码剖析数据结构篇(十一) 共享内存ngx_shm_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn ...

  2. 菜鸟nginx源码剖析数据结构篇(九) 内存池ngx_pool_t[转]

    菜鸟nginx源码剖析数据结构篇(九) 内存池ngx_pool_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn. ...

  3. 菜鸟nginx源码剖析数据结构篇(八) 缓冲区链表ngx_chain_t[转]

    菜鸟nginx源码剖析数据结构篇(八) 缓冲区链表 ngx_chain_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.c ...

  4. 菜鸟nginx源码剖析数据结构篇(七) 哈希表 ngx_hash_t(下)[转]

    菜鸟nginx源码剖析数据结构篇(七) 哈希表 ngx_hash_t(下) Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.c ...

  5. 菜鸟nginx源码剖析数据结构篇(六) 哈希表 ngx_hash_t(上)[转]

    菜鸟nginx源码剖析数据结构篇(六) 哈希表 ngx_hash_t(上) Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.c ...

  6. 菜鸟nginx源码剖析数据结构篇(五) 基数树 ngx_radix_tree_t[转]

    菜鸟nginx源码剖析数据结构篇(五) 基数树 ngx_radix_tree_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blo ...

  7. 菜鸟nginx源码剖析数据结构篇(四)红黑树ngx_rbtree_t[转]

    菜鸟nginx源码剖析数据结构篇(四)红黑树ngx_rbtree_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn ...

  8. 菜鸟nginx源码剖析数据结构篇(三) 单向链表 ngx_list_t[转]

    菜鸟nginx源码剖析数据结构篇(三) 单向链表 ngx_list_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csd ...

  9. 菜鸟nginx源码剖析数据结构篇(一)动态数组ngx_array_t[转]

    菜鸟nginx源码剖析数据结构篇(一)动态数组ngx_array_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn ...

随机推荐

  1. Spring Cloud Eureka 注册安全一定要做到位!

    /eureka/ 参考配置如下: defaultZone: http://javastack:javastack@eureka1:8761/eureka/, http://javastack:java ...

  2. 使用SDK方式进行微信授权

    1.在pom.xml中添加依赖 <dependency> <groupId>com.github.binarywang</groupId> <artifact ...

  3. 在CentOS 7上安装常用的YUM源

    参考地址:https://blog.csdn.net/u010048823/article/details/51298183 以epel源为例子,来讲解如何添加额外的YUM源. Extra Packa ...

  4. java哈希表(线性探测哈希表。链式哈希表)

    哈希表(散列表) 通过哈希函数使元素的存储位置与它 的关键码之间能够建立一一映射的关系,在查找时可以很快找到该元素. 哈希表hash table(key,value) 的做法其实很简单,就是把Key通 ...

  5. Batch pk Shell - WindowsBatch与LinuxShell比较 [变量符号和关键字]

    原文地址:WindowsBatch与LinuxShell比较[变量符号和关键字] 一 简单实例1)batch file @echo off rem output helloworld ::  outp ...

  6. CSS——滑动门技术及应用

    先来体会下现实中的滑动门,或者你可以叫做推拉门: 滑动门出现的背景 制作网页时,为了美观,常常需要为网页元素设置特殊形状的背景,比如微信导航栏,有凸起和凹下去的感觉,最大的问题是里面的字数不一样多,咋 ...

  7. nginx反向代理时有无”/”的辨析

    nginx反向代理是日常使用nginx时最常用到的功能之一.在配置url的过程中,“/”的有无经常是影响我们配置成功的关键,也是困扰我们的问题所在.在此,结合实际例子,作简要辨析. 场景一:利用根目录 ...

  8. 学习Caffe(一)使用Caffe

    如何使用Caffe Caffe教程(http://robots.princeton.edu/courses/COS598/2015sp/slides/Caffe/caffe_tutorial.pdf) ...

  9. Vuex听说很难?

    Vuex 是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件状态,并以相应的规则保证状态以一种可预测的方式发生变化.   什么鬼东西 看完这段 ...

  10. Docker系列(九):Kubernetes架构深度解析

    Kubernetes重要概念 Docker解决了打包和隔离的问题,但我们需要更多:调度的问题,生命周期及健康状况,服务发现,监控,认证,容器聚合. Kubernetes概述 开源DOcker容器编排系 ...