linux 读写锁(写优先)使用方法

http://sourceware.org/ml/glibc-bugs/2008-11/msg00073.html

http://www.nabble.com/-Bug-nptl-7057--New:-pthread-rwlock-does-not-implement-'writer-preferred'-option-td20703744.html

 

pthread rwlock does not implement 'writer preferred' option

 

 

linux 读写锁

定义(全局变量):
pthread_rwlock_t    rw_lock;


初始化:
{
    pthread_rwlockattr_t attr;
    int ret = 0;

    ret = pthread_rwlockattr_init( &attr );
    if( ret < 0 )
    {
 ...;
        return;
    }

#ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
    pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP); // 写优先
#endif

    ret = pthread_rwlockattr_setpshared( &attr, PTHREAD_PROCESS_SHARED );  // 进程内
    if( ret < 0 )
    {
        ...;
        return;
    }

    ret = pthread_rwlock_init( &rw_lock, &attr );
    if( ret < 0 )
    {
        ...;
        return;
    }


    ret = pthread_rwlockattr_destroy( &attr );
    if( ret < 0 )
    {
        ...;
        return;
    }

    return;
}

 

使用:
    // 写锁
    pthread_rwlock_wrlock(&rw_lock);
    ......
    pthread_rwlock_unlock(&rw_lock);

    // 读锁
    pthread_rwlock_rdlock(& w_lock);
    ......
    pthread_rwlock_unlock(&rw_lock);

 

 

另外一个:

  #define   _XOPEN_SOURCE   500   
      #include   <pthread.h>   
      #   define   PTHREAD_RWLOCK_INITIALIZER_READ_PREF       {   {0,   0},   0,   NULL,   NULL,   NULL,                                         PTHREAD_RWLOCK_PREFER_READER_NP,   PTHREAD_PROCESS_PRIVATE   }  
   
  static   pthread_rwlock_t   a   =   PTHREAD_RWLOCK_INITIALIZER;  
   
  void   *route_3   (void   *p)  
  {  
                  sleep(2);  
                  printf("locking   3   =   %d/n",   pthread_rwlock_rdlock(&a));  
                  pause();  
                  return   NULL;  
  }  
   
  void   *route_2   (void   *p)  
  {  
                  sleep(1);  
                  printf("locking   2   =   %d/n",   pthread_rwlock_wrlock(&a));  
                  pause();  
                  return   NULL;  
  }  
   
  void   *route_1   (void   *p)  
  {  
                  printf("locking   1   =   %d/n",   pthread_rwlock_rdlock(&a));  
                  pause();  
                  return   NULL;  
  }  
   
  main()  
  {  
                  pthread_t   t1,   t2,   t3;  
                  pthread_create(&t1,   NULL,   route_1,   NULL);  
                  pthread_create(&t2,   NULL,   route_2,   NULL);  
                  pthread_create(&t3,   NULL,   route_3,   NULL);  
                  pthread_join(t1,   NULL);  
                  pthread_join(t2,   NULL);  
                  pthread_join(t3,   NULL);  
  }  
   
  这个例子如果把a初始化成PTHREAD_RWLOCK_INITIALIZER_READ_PREF   ,才是读优先的,你可以试一下,如果不对,就只有怀疑线程库看源码了。  

读写锁是用于多线程环境下保护共享资源的一种机制。在 Linux 内核中,读写锁的实现是基于 spinlock 和原子操作的。下面我将简单介绍一下 Linux 内核中读写锁的源码实现。 读写锁的定义: ```c typedef struct { raw_rwlock_t raw_lock; } rwlock_t; ``` 其中,raw_rwlock_t 是一个原始读写锁类型,它是由内核提供的一个结构体类型,定义在 include/linux/spinlock_types.h 文件中。 raw_rwlock_t 的定义: ```c typedef struct { arch_rwlock_t raw_lock; } raw_rwlock_t; typedef struct { unsigned int lock; } arch_rwlock_t; ``` 其中,arch_rwlock_t 是一个体系结构相关的原始读写锁类型,它的实现由不同的处理器架构提供。 下面是 x86_64 架构下的 arch_rwlock_t 实现: ```c struct __arch_rwlock { unsigned int lock; }; typedef struct __arch_rwlock arch_rwlock_t; ``` 可以看到,在 x86_64 架构下,arch_rwlock_t 只包含一个 unsigned int 类型的 lock 成员变量,用于存储锁状态。 读写锁的初始化: ```c void rwlock_init(rwlock_t *lock) { raw_spin_lock_init(&lock->raw_lock.spinlock); atomic_long_set(&lock->raw_lock.rw_sem, 0); } ``` 其中,raw_spin_lock_init() 用于初始化锁,atomic_long_set() 用于初始化读计数器。 读锁的获取: ```c void read_lock(rwlock_t *lock) { while (1) { long count = atomic_long_read(&lock->raw_lock.rw_sem); if (count >= 0) { if (atomic_long_cmpxchg(&lock->raw_lock.rw_sem, count, count + 1) == count) { break; } } else { cpu_relax(); } } raw_spin_lock(&lock->raw_lock.spinlock); } ``` 其中,atomic_long_read() 用于读取读计数器的值,如果值大于等于 0,则表示读锁可用,此时使用 atomic_long_cmpxchg() 原子操作来增加读计数器并获取读锁;如果值小于 0,则表示有锁在使用,此时使用 cpu_relax() 函数等待锁释放。 读锁的释放: ```c void read_unlock(rwlock_t *lock) { raw_spin_unlock(&lock->raw_lock.spinlock); atomic_long_dec(&lock->raw_lock.rw_sem); } ``` 其中,raw_spin_unlock() 用于释放锁,atomic_long_dec() 用于减少读计数器的值。 锁的获取: ```c void write_lock(rwlock_t *lock) { raw_spin_lock(&lock->raw_lock.spinlock); while (1) { long count = atomic_long_read(&lock->raw_lock.rw_sem); if (count == 0) { if (atomic_long_cmpxchg(&lock->raw_lock.rw_sem, 0, -1) == 0) { break; } } else { cpu_relax(); } } } ``` 其中,raw_spin_lock() 用于获取锁,atomic_long_read() 用于读取读计数器的值,如果值等于 0,则表示读锁未被使用,此时使用 atomic_long_cmpxchg() 原子操作将读计数器的值修改为 -1 并获取锁;如果值大于 0,则表示有读锁在使用,此时使用 cpu_relax() 函数等待读锁释放。 锁的释放: ```c void write_unlock(rwlock_t *lock) { atomic_long_set(&lock->raw_lock.rw_sem, 0); raw_spin_unlock(&lock->raw_lock.spinlock); } ``` 其中,atomic_long_set() 用于将读计数器的值设为 0,raw_spin_unlock() 用于释放锁。 以上就是 Linux 内核中读写锁的源码实现。值得注意的是,在多处理器环境下,读写锁的实现可能会涉及到更复杂的机制,例如优先等待、读者优先等待等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值