并发和竞争发生在两类体系中:
  对称多处理器(SMP)的多个CPU
  内核可抢占的单CPU系统
  访问共享资源的代码区域称为临界区(critical sections),临界区需要以某种互斥机制加以保护。在驱动程序中,当多个线程同时访问相同的资源(critical sections)时(驱动程序中的全局变量是一种典型的共享资源),可能会引发”竞态”,因此我们必须对共享资源进行并发控制。Linux内核中解决并发控制的方法又中断屏蔽、原子操作、自旋锁、信号量。(后面为主要方式)
  中断屏蔽:
  使用方法
  local_irq_disable() //屏蔽中断
  ...
  critical section //临界区
  ...
  local_irq_enable() //开中断
  local_irq_disable/enable只能禁止/使能本CPU内的中断,不能解决SMP多CPU引发的竞态,故不推荐使用,其适宜于自旋锁联合使用。
  原子操作:
  原子操作是一系列的不能被打断的操作。linux内核提供了一系列的函数来实现内核中的原子操作,这些函数分为2类,分别针对位和整型变量进行原子操作。
  实现整型原子操作的步骤如下:
  1.定义原子变量并设置变量值
  void atomic_set(atomic_t *v , int i); //设置原子变量值为i
  atomic_t v = ATOMIC_INIT(0); //定义原子变量v,初始化为0
  2.获取原子变量的值
  atomic_read(atomic_t *v);
  3.原子变量加减操作
  void atomic_add(int i,atomic_t *v);//原子变量加i
  void atomic_sub(int i ,atomic_t *v);//原子变量减i
  4.原子变量自增/自减
  void atomic_inc(atomic_t *v);//自增1
  void atomic_dec(atomic_t *v);//自减1
  5.操作并测试:对原子变量执行自增、自减后(没有加)测试其是否为0,如果为0返回true,否则返回false。
  int atomic_inc_and_test(atomic_t *v);
  int atomic_dec_and_test(atomic_t *v);
  int atomic_sub_and_test(int i ,atomic_t *v);
  6.操作并返回
  int atomic_add_return(int i , atomic_t *v);
  int atomic_sub_return(int i , atomic_t *v);
  int atomic_inc_return(atomic_t * v);
  int atomic_dec_return(atomic_t * v);
  实现 位原子操作如下:
  // 设置位
  void set_bit(nr, void *addr); // 设置addr地址的第nr位,即将位写1
  // 清除位
  void clear_bit(nr, void *addr); // 清除addr地址的第nr位,即将位写0
  // 改变位
  void change_bit(nr, void *addr); // 对addr地址的第nr位取反
  // 测试位
  test_bit(nr, void *addr); // 返回addr地址的第nr位
  // 测试并操作:等同于执行test_bit(nr, void *addr)后再执行xxx_bit(nr, void *addr)
  int test_and_set_bit(nr, void *addr);
  int test_and_clear_bit(nr, void *addr);
  int test_and_change_bit(nr, void *addr)