Linux设备驱动中的并发控制

并发是多个执行单元同时 并行被执行。而并发的执行单元对共享资源(硬件资源和软件上的全局变量,静态变量)的访问很容易导致竞态。

主要的竞态有以下三种情况:对称多处理器(SMP)的多个CPU;单个CPU内进程与抢占它的进程;中断(硬中断,软中断,Tasklet 底半部)与进程之间。

注:上述情况,除了SMP是真正的并行之外,其他的都是“宏观并行,微观串行”,但其引发的问题和SMP相似。

解决竞态问题的途径是保证对共享资源的互斥访问,即:当一个进程访问的时候,其他的进程单元禁止访问。

访问共享资源的代码区称为临界区。访问临界区即需要加互斥机制。

实现互斥访问的途径有如下几种:

1 . 中断屏蔽
2 . 原子操作
3 . 自旋锁
4 . 信号量 

1 . 中断屏蔽

CPU 一般都具备屏蔽中断和打开中断的功能,这使得正在执行的内核执行路径不被中断处理程序抢占,防止了竞态的放生

使用方法:

local_irq_disable()//屏蔽中断

。。。

critical section //临界区

。。。

local_irq_enable()//开启中断

2 . 原子操作

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

有两类函数可以实现原子操作:针对位 和针对整形变量的操作

整型原子操作:

1 设置原子变量的值

void atomic_set(atomic_t  *v,int  t);//设置值为i

atomic_t v= ATOMIC_INIT(0);//初始化

2 获取原子变量的值

atomic_read(atomic_t *v);

3 原子变量加/减

void atomic_add(atomic_t *v);

void atomic_sub(atomic_t *v);

4 原子变量自增/自减

void atomic_inc(atomic_t *v);

void atomic_dec(atomic_t *v);

5 操作并测试

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);

位原子操作

1 设置位

void set_bit(nr,void *addr)

2 清除位

void clear_bit(nr,void *addr)

3 改变位

void change_bit(nr,void *addr)

4 测试位

void test_bit(nr,void *addr)

5 测试并操作

int test_and_set_bit(nr,void *addr);

int test_and_clear_bit(nr,void *addr);

int test_and_change_bit(nr,void *addr);

linux

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/3dbba59f78cf5d407306d362e27fa56a.html