Linux并发控制--------原子操作、自旋锁、RCU、信号量、互斥体和完成量

Linux 驱动中实现并发控制,由此产生了并发控制的技术。

这些技术包括: 原子操作、自旋锁、RCU、信号量、互斥体和完成量

主要的并发控制技术

  • 原子操作
  • 自旋锁(Spin lock)
  • 读-复制-更新(RCU)机制
  • 信号量(Semaphore)
  • 互斥体(Mutex)
  • 完成量(Completion)

原子操作:

  原子操作指的是在执行过程中不会被别的代码路径所中断的操作。

  或者 “可被中断的一个或一系列操作”

  原子操作分为两类:整型原子操作、位原子操作


 2.1 整型原子操作:
 
 设置原子变量的值:
 
  void atomic_set(atomic_t *v, int i); /* 设置原子变量的值为 i */
 
 
  atomic_t v = ATOMIC_INIT(0); /* 定义原子变量 v ,初始化为0 */
 
 
 获取原子变量的值:
 
  atomic_read(atomic_t *v); /* 返回原子变量的值 */
 
 
 加/减:
 
  void atomic_add(int i, atomic_t *v); /* 原子变量增加i */
 
 
  void atomic_sub(int i, atomic_t *v); /* 原子变量减少i */
 
 
 自增/自减:
 
  void atomic_inc(atomic_t *v); /* 自加1 */
 
 
  void atomic_dec(atomic_t *v); /* 自减1 */
 
 
 操作并测试:
 
  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);
 

  对原子变量执行自增、自减和减操作后(无加)测试其是否为 0,

  0,true

  !0,false
 
 操作并返回:
 
  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);
 

  执行完操作后,返回新的值


 2.2 位原子操作:
 
 置位: -- 置1
 
  void set_bit(nr, void *addr);
 

  功能:
 
  将 addr 地址的第 nr 位置为 1
 
 
 清零:
 
  void clear_bit(nr, void *addr);
 
 
 位翻转:
 
  void change_bit(nr, void *addr);
 
 
 测试:
 
  test_bit(nr, void *addr);
 

  功能:
 
  返回 addr 位的第 nr 位
 
 
 测试并操作:
 
  int test_and_set_bit(nr, void *addr);
 
 
  int test_and_clear_bit(nr, void *addr);
 
 
  int test_and_change_bit(nr, void *addr);
 

  功能:
 
  相当于先执行了test_bit(nr, void *addr)后再执行 xxx_bit(nr, void *addr)
 
  
 3. 原子操作的实例:

  实现 设备最多只能被一个进程打开:
 关键的函数:


atomic_t v = ATOMIC_INIT(1);  
  
static int hello_open (struct inode *inode, struct file *file)  
{  
    if (!atomic_dec_and_test(&v))  
    {  
        atomic_inc(&v);  
        return -EBUSY;  
    }  
    printk (KERN_INFO "Hey! device opened\n");  
  
    return 0;  
}  
  
static int hello_release (struct inode *inode, struct file *file)  
{  
    atomic_inc(&v);   
    printk (KERN_INFO "Hmmm! device closed\n");  
  
    return 0;  
}  


  函数说明:(hello_open函数)
 
  ①第一次打开设备驱动的时候 v = 1,v - 1 = 0 ,atomic_dec_and_test(&v) 结果是 true,不进循环,不返回EBUSY,执行下边内容。
 

  ②第二次打开设备驱动,v = 0, v - 1 = -1,atomic_dec_and_test(&v) 结果是 false,进循环,直接返回。
 
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值