linux读写锁的理解

yuan

百度百科http://baike.baidu.com/view/2214179.htm上这样说:

读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。这种锁相对于自旋锁而言,能提高并发性,因为在多处理器系统中,它允许同时有多个读者来访问共享资源,最大可能的读者数为实际的逻辑CPU数。写者是排他性的,一个读写锁同时只能有一个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者。

那么读写锁到底如何实现的,研究了一把Linux内核源码:

[cpp]  view plain copy
  1. #define RW_LOCK_BIAS         0x01000000  
  2. #define RW_LOCK_BIAS_STR    "0x01000000"  
  3.   
  4. #if defined(CONFIG_SMP)  
  5. asm(  
  6. "  
  7. .align    4  
  8. .globl    __write_lock_failed  
  9. __write_lock_failed:  
  10.     " LOCK "addl    $" RW_LOCK_BIAS_STR ",(%eax)  
  11. 1:    cmpl    $" RW_LOCK_BIAS_STR ",(%eax)  
  12.     jne    1b  
  13.   
  14.     " LOCK "subl    $" RW_LOCK_BIAS_STR ",(%eax)  
  15.     jnz    __write_lock_failed  
  16.     ret  
  17.   
  18.   
  19. .align    4  
  20. .globl    __read_lock_failed  
  21. __read_lock_failed:  
  22.     lock ; incl    (%eax)  
  23. 1:    cmpl    $1,(%eax)  
  24.     js    1b  
  25.   
  26.     lock ; decl    (%eax)  
  27.     js    __read_lock_failed  
  28.     ret  
  29. "  
  30. );  
  31. #endif  
  32.   
  33. #define __build_read_lock_ptr(rw, helper)   \  
  34.     asm volatile(LOCK "subl $1,(%0)\n\t" \  
  35.              "js 2f\n" \  
  36.              "1:\n" \  
  37.              ".section .text.lock,\"ax\"\n" \  
  38.              "2:\tcall " helper "\n\t" \  
  39.              "jmp 1b\n" \  
  40.              ".previous" \  
  41.              ::"a" (rw) : "memory")  
  42.   
  43. #define __build_write_lock_ptr(rw, helper) \  
  44.     asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \  
  45.              "jnz 2f\n" \  
  46.              "1:\n" \  
  47.              ".section .text.lock,\"ax\"\n" \  
  48.              "2:\tcall " helper "\n\t" \  
  49.              "jmp 1b\n" \  
  50.              ".previous" \  
  51.              ::"a" (rw) : "memory")  
  52.   
  53. #define read_unlock(rw)        asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory")  
  54. #define write_unlock(rw)    asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")  
  55.   
  56.   
  57. static rwlock_t file_systems_lock = RW_LOCK_UNLOCKED;  
  58. #define RW_LOCK_UNLOCKED (rwlock_t) { RW_LOCK_BIAS RWLOCK_MAGIC_INIT }  

从上面可以看出:

读写锁本质上是一个内存计数器,初始化成一个很大的值(第57-58行)0x01000000,表示最多可以有这么多个读者同时获取锁。

1. 获取读锁时,计数器减1,判断符号位是否为1,也就是判断是否为负数,是则表示已经有写者,读锁获取失败。符号位为0则获取读锁成功。

2. 获取写锁时,计数器减0x01000000,判断是否为0,是则表示没有其他的读者或者写者,获取锁成功。不为0,则有其他的读者或者写者,获取写锁失败。

3. 获取读锁失败时,先将计数器加1,判断值是否小于1(减1符号位为1),是则循环判读,直到值大于1。获取读锁失败的情况是已有写者,计数器的值小于等于0。

4. 获取写锁失败时,先讲计数器加0x01000000,判断值是否为0x01000000,不为0x01000000则循环判断,直到为0x01000000。为初值0x01000000表示没有了其他的读者或者写者,可以尝试获取锁了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值