菜鸟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的更多相关文章

    1. 菜鸟nginx源代码剖析数据结构篇(一)动态数组ngx_array_t

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

    2. 菜鸟nginx源代码剖析数据结构篇(八) 缓冲区链表ngx_chain_t

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

    3. 菜鸟nginx源代码剖析数据结构篇(六) 哈希表 ngx_hash_t(上)

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

    4. 菜鸟nginx源代码剖析数据结构篇(九) 内存池ngx_pool_t

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

    5. 菜鸟nginx源代码剖析数据结构篇(七) 哈希表 ngx_hash_t(下)

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

    6. 菜鸟nginx源代码剖析 框架篇(一) 从main函数看nginx启动流程

      菜鸟nginx源代码剖析 框架篇(一) 从main函数看nginx启动流程 Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.c ...

    7. 新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t

      新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csd ...

    8. 新秀nginx源代码分析数据结构篇(两) 双链表ngx_queue_t

      nginx源代码分析数据结构篇(两) 双链表ngx_queue_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn. ...

    9. 菜鸟nginx源代码剖析 配置与部署篇(一) 手把手实现nginx &quot;I love you&quot;

      菜鸟nginx源代码剖析 配置与部署篇(一) 手把手配置nginx "I love you" Author:Echo Chen(陈斌) Email:chenb19870707@gm ...

    随机推荐

    1. javascript中for...in和for...of的区别

      for...of循环是ES6引入的新的语法. for...in遍历拿到的x是键(下标).而for...of遍历拿到的x是值,但在对象中会提示不是一个迭代器报错.例子如下: let x; let a = ...

    2. [ JSOI 2015 ] Salesman

      \(\\\) \(Description\) 给出一棵以\(1\)为根的\(N\)个节点的树,开始的时候你在\(1\)号节点. 除了\(1\)号节点以外,每个点都有访问次数限制\(t_i\),即到达该 ...

    3. drupal 8 ——自定义权限

      在项目开发里面,我遇到了这么一个需求,就是对于node的title字段,编辑内容的角色不允许对title进行编辑.title字段是创建内容类型时自动生成的字段,不能在drupal8后台直接配置权限,所 ...

    4. Ch03 React/JSX/Component 簡介

      Facebook 本身有提供 Test Utilities,但由于不够好用,所以目前主流开发社群比较倾向使用 Airbnb 团队开发的 enzyme,其可以与市面上常见的测试工具(Mocha.Karm ...

    5. UITableview 兼容IOS6 和IOS7的方法

      1. TableVIew向下拉44像素  添加Auto layout 2. Extended edge 选择Under top bars 2. 在Viewdidload中添加代码 if ([[UIDe ...

    6. CDR软件-CorelDRAW软件下载,618活动

      618我有诚意,你呢? 不花钱的618,是残缺的618 给自己一个放肆shopping的机遇 活动力度不够大? 继续升级,终极体验 618疯狂倒计时! 同志们,如果你错过了之前的抢先购和升级活动 那么 ...

    7. uva 1401

      Neal is very curious about combinatorial problems, and now here comes a problem about words. Knowing ...

    8. C# Thu Mar 1 00:00:00 UTC+0800 2012 如何转换为2012-03-01

      string s = "Thu Mar 1 00:00:00 UTC+0800 2012"; DateTime dt = DateTime.ParseExact(s, " ...

    9. 计蒜客 劫富济贫 (Trie树)

      链接 : Here! 思路 : Trie树裸题, 由开始给出的名字建一棵字典树, 然后每次查询一下抢♂劫的人名是否在字典树中, 复杂度也不清楚是多少, 反正是没给出 $M$ 的范围, 开始时用 $ha ...

    10. Luogu P2298 Mzc和男家丁的游戏

      Mzc和男家丁的游戏 题目背景 mzc与djn的第二弹. 题目描述 mzc家很有钱(开玩笑),他家有n个男家丁(做过上一弹的都知道).他把她们召集在了一起,他们决定玩捉迷藏.现在mzc要来寻找他的男家 ...