Linux设备驱动中的并发控制

2014-11-24 09:07:17 ? 作者: ? 浏览: 0

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


主要的竞态有以下三种情况:对称多处理器(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);


-->

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: