读写自旋锁一般用法:
  rwlock_t lock; // 定义rwlock
  rwlock_init(&lock); // 初始化rwlock
  // 读时获取锁
  read_lock(&lock);
  ... // 临界资源
  read_unlock(&lock);
  // 写时获取锁
  write_lock_irqsave(&lock, flags);
  ... // 临界资源
  write_unlock_irqrestore(&lock, flags);
  顺序锁(seqlock):
  顺序锁是对读写锁的一种优化,若使用顺序锁,读与写操作不阻塞,只阻塞同种操作,即读与读/写与写操作。
  写执行单元的操作顺序如下:
  //获得顺序锁
  void write_seqlock(seqlock_t *s1);
  int write_tryseqlock(seqlock_t *s1);
  write_seqlock_irqsave(lock, flags)
  write_seqlock_irq(lock)
  write_seqlock_bh(lock)
  //释放顺序锁
  void write_sequnlock(seqlock_t *s1);
  write_sequnlock_irqrestore(lock, flags)
  write_sequnlock_irq(lock)
  write_sequnlock_bh(lock)
  读执行单元的操作顺序如下:
  //读开始
  unsinged read_seqbegin(const seqlock_t *s1);
  read_seqbegin_irqsave(lock, flags)
  //重读,读执行单元在访问完被顺序锁s1保护的共享资源后需要调用该函数来检查在读操作器件是否有写操作,如果有,读执行单元需要从新读一次。
  int reead_seqretry(const seqlock_t *s1, unsigned iv);
  read_seqretry_irqrestore(lock, iv, flags)
  RCU(Read-Copy Update 读-拷贝-更新)可看作读写锁的高性能版本,既允许多个读执行单元同时访问被保护的数据,又允许多个读执行单元和多个写执行单元同时访问被保护的数据。但是RCU不能替代读写锁。因为如果写操作比较多时,对读执行单元的性能提高不能弥补写执行单元导致的损失。因为使用RCU时,写执行单元之间的同步开销会比较大,它需要延迟数据结构的释放,复制被修改的数据结构,它也必须使用某种锁机制同步并行的其他写执行单元的修改操作。
  具体操作:略
  信号量的使用
  信号量(semaphore)与自旋锁相同,只有得到信号量才能执行临界区代码,但,当获取不到信号量时,进程不会原地打转而是进入休眠等待状态。
  相同点:只有得到信号量的进程才能执行临界区的代码。(linux自旋锁和信号量锁采用的都是“获得锁-访问临界区-释放锁”,可以称为“互斥三部曲”,实际存在于几乎所有多任务操作系统中)
  不同点:当获取不到信号量时,进程不会原地打转而是进入休眠等待状态。
  信号量的操作:
  /信号量的结构
  struct semaphore sem;
  //初始化信号量
  void sema_init(struct semaphore *sem, int val)
  //常用下面两种形式
  #define init_MUTEX(sem) sema_init(sem, 1)
  #define init_MUTEX_LOCKED(sem) sema_init(sem, 0)
  //以下是初始化信号量的快捷方式,常用的
  DECLARE_MUTEX(name) //初始化name的信号量为1
  DECLARE_MUTEX_LOCKED(name) //初始化信号量为0
  //常用操作
  DECLARE_MUTEX(mount_sem);
  down(&mount_sem); //获取信号量
  ...
  critical section //临界区
  ...
  up(&mount_sem); //释放信号量
  信号量用于同步时只能唤醒一个执行单元,而完成量(completion)用于同步时可以唤醒所有等待的执行单元。
  自旋锁与互斥锁的选择
  当锁 不能被获取到时,使用信号量的开销是进程上下文切换时间Tsw,使用自旋锁的开始是等待获取自旋锁的时间Tcs,若Tcs比较小,则应使用自旋锁,否则应使用信号量
  信号量锁保护的临界区可以包含引起阻塞的代码,而自旋锁则却对要避免使用包含阻塞的临界区代码,否则很可能引发锁陷阱
  信号量存在于进程上下文,因此,如果被保护的共享资源需要在中断或软中断情况下使用,则在信号量和自旋锁之间只能选择自旋锁。当然,如果一定要使用信号量,则只能通过down_trylock()方式进行,不能获取立即返回以避免阻塞。