首页 > 代码库 > linux设备驱动中的并发控制

linux设备驱动中的并发控制

并发控制的概念

----并发指的是多个执行单元并行执行,而并发的执行单元对共享资源(硬件资源和

----软件上的全局变量、静态变量等)的访问则很容易导致竞态。

竞态发生的情况

----对称多处理器(SMP)的多个CPU

----单CPU内进程与抢占它的进程

----中断(硬中断、软中断、Tasklet、底半部)与进程之间

解决竞态问题的途径

----保证对共享资源的互斥访问,所谓互斥访问是指一个执行单元在访问共享资源的时候,

----其他的执行单元被禁止访问。

----访问共享资源的代码称为临界区,临界区需要被以某种互斥机制加以保护。

互斥机制

----中断屏蔽

----原子操作

----自旋锁

----信号量

中断屏蔽

----local_irq_disable()   //屏蔽中断

----/*临界区*/

----local_irq_enable()   //开中断

----这种方式并不能解决SMP多CPU引发的竞态

原子操作

----实现方法:

----头文件asm/atomic.h

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

----if(! atomic_dec_and_test(v))           //自减1测试

----{ atomic_inc(&v);  return –EBUSY; }  //设备忙返回错误码

---- ……                                       //临界区代码

----atomic_inc(&c);                     //释放设备

自旋锁

----spinlock_t  lock;            //定义自旋锁

----spin_lock_init(&lock);    //初始化自旋锁

----spin_lock(&lock);        //获得自旋锁

----……                               //临界区代码

----spin_unlock(&lock);      //释放自旋锁

----一个例子:

static int cdev_open(struct inode*inode, struct file *file)

{

         spin_lock(&lock);

         if(flag== 1){

                   flag--;

                   spin_unlock(&lock);

                   printk(KERN_INFO"cdev_open !\n");      //临界区代码

                   return0;

         }else{

                   spin_unlock(&lock);

                   return-EBUSY;

         }

         return0;

}

static int cdev_release(struct inode*inode, struct file *file)

{

         flag++;

return 0;

}

----说明:自旋锁是一种忙等待锁,中间不能有可引起睡眠的操作;临界区不能太长;自旋

----锁可用在中断上下文中

信号量

----需要头文件linux/semaphore.h

----struct semaphore  sem;         //定义信号量

----sema_init(&sem,1);                //初始化信号量

----down_interruptible(&sem);    //获取信号量

----……                                         //临界区代码

----up(&sem);                              //释放信号量

----说明:信号量不同于自旋锁,他是一种睡眠锁,不能用在中断上下文中。

----一种简单的使用方法:

----if(down_trylock(&sem))   //尝试打开锁

----return  –EBUSY;       //设备忙

----……                           //临界区代码

----up(&sem);                 //释放打开的锁

 

 

 

 

 

linux设备驱动中的并发控制