菜鸟nginx源代码剖析数据结构篇(十) 自旋锁ngx_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

-

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值