Linux驱动开发八:按键中断+poll机制+异步通知机制+信号量及阻塞标志



目的:

         同一时刻只能有一个应用程序打开设备

 

解决方案:

1. 原子操作

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

常用原子操作函数举例:

atomic_t v = ATOMIC_INIT(0);     //定义原子变量v并初始化为0

atomic_read(atomic_t *v);        //返回原子变量的值

void atomic_inc(atomic_t *v);    //原子变量增加1

void atomic_dec(atomic_t *v);    //原子变量减少1

int atomic_dec_and_test(atomic_t *v); //自减操作后测试其是否为0,为0则返回true,否则返回false

所谓原子操作,就是该操作绝不会在执行完毕前被任何其他任务或事件打断,也就说,它的最小的执行单位,不可能有比它更小的执行单位,因此这里的原子实际是使用了物理学里的物质微粒的概念。

  原子操作需要硬件的支持,因此是架构相关的,其API和原子类型的定义都定义在内核源码树的include/asm/atomic.h文件中,它们都使用汇编语言实现,因为C语言并不能实现这样的操作。

  原子操作主要用于实现资源计数,很多引用计数(refcnt)就是通过原子操作实现的

 

并发:

          多个执行单元同时被执行.

 

竞态:

          并发的执行单元对资源 ( 硬件资源和软件上的全局变量等 ) 的访问导致的竞争状态.

          https://img-my.csdn.net/uploads/201303/08/1362719582_8444.jpg

 

并发的处理:

          处理并发的常用技术是加锁或者互斥,即保证在任何时间只有一个执行单元可以操作共享资源.

          Linux 内核中主要通过 semaphore 机制 (信号量)spin_lock 机制 (自旋锁)实现.

 

原子操作:

定义:

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

分为 整型变量 两类原子操作。

 

atomic_t  

[cpp] view plaincopyprint?

1. typedef struct {  

2. volatile int counter;  

3. } atomic_t;  

typedefstruct {

volatileint counter;

}atomic_t;

原子操作函数:

整型原子操作:

[cpp] view plaincopyprint?

1. void atomic_set(atomic_t *v, int i);   //设置原子变量v的值为i  

2. atomic_t v = ATOMIC_INIT(0);            //定义原子变量v 并初始化为0  **************************  

3. atomic_read(atomic_t *v);              //获得原子变量的值,返回原子变量的值  

4. void atomic_add(int i, atomic_t *v);    //原子变量+i  

5. void atomic_sub(int i, atomic_t *v);    //原子变量-i  

6. void atomic_inc(atomic_t *v);           //原子变量+1            *******************************  

7. void atomic_dec(atomic_t *v);           //原子变量-1  

voidatomic_set(atomic_t *v, int i);   //设置原子变量v的值为i

atomic_tv = ATOMIC_INIT(0);            //定义原子变量v, 并初始化为0  **************************

atomic_read(atomic_t*v);              //获得原子变量的值,返回原子变量的值

voidatomic_add(int i, atomic_t *v);    //原子变量+i

voidatomic_sub(int i, atomic_t *v);    //原子变量-i

voidatomic_inc(atomic_t *v);           //原子变量+1            *******************************

voidatomic_dec(atomic_t *v);           //原子变量-1

 

对原子变量执行自增,自减和减操作后 ,测试其是否为0,为 0 则返回 true,否则返回 false

[cpp] view plaincopyprint?

1. int atomic_inc_and_test(atomic_t *v);   

2. int atomic_dec_and_test(atomic_t *v);              ***********************  

3. int atomic_sub_and_test(int i, atomic_t *v);          

intatomic_inc_and_test(atomic_t *v);

intatomic_dec_and_test(atomic_t *v);             ***********************

intatomic_sub_and_test(int i, atomic_t *v);       

 

对原子变量进行加/减,自增/自减操作,并返回新的值:

[cpp] view plaincopyprint?

1. int atomic_add_return(int i, atomic_t *v);  

2. int atomic_sub_return(int i, atomic_t *v);  

3. int atomic_inc_return(atomic_t *v);  

4. int atomic_sub_return(atomic_t *v);  

intatomic_add_return(int i, atomic_t *v);

intatomic_sub_return(int i, atomic_t *v);

intatomic_inc_return(atomic_t *v);

intatomic_sub_return(atomic_t *v);

位原子操作:

[cpp] view plaincopyprint?

1. void set_bit(nr, void *addr);    //addr地址的nr 置为1  

2. void clear_bit(nr, void *addr);  //addr地址的nr 0  

3. void change_bit(nr, void *addr);  //addr地址的nr 反置  

4. int test_bit(nr, void *addr);    //返回addr地址的nr  

5. 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值