目的:
同一时刻只能有一个应用程序打开设备
解决方案:
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)就是通过原子操作实现的
多个执行单元同时被执行.
并发的执行单元对资源 ( 硬件资源和软件上的全局变量等 ) 的访问导致的竞争状态.
处理并发的常用技术是加锁或者互斥,即保证在任何时间只有一个执行单元可以操作共享资源.
在 Linux 内核中主要通过 semaphore 机制 (信号量)和spin_lock 机制 (自旋锁)实现.
原子操作指的是在执行过程中不会被别的代码所中断的操作.
分为 位 和 整型变量 两类原子操作。
[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.