标签:
产生竞态的情况:
(1)对称多处理器(SMP)的多个CPU
(2)单CPU的进程与抢占它的进程
(3)中断与进程之间
解决竞态途径:互斥访问
临界区:访问共享资源的代码区
互斥途径:中断屏蔽、原子操作、自旋锁、信号量、互斥体
中断屏蔽
local_irq_disable() /*屏蔽中断*/
...
critical section /*临界区 */
...
local_irq_enable() /*开中断 */
中断屏蔽只能禁止和使能本CPU内的中断,不能解决SMP多CPU的竞态问题,不推荐使用。
/*禁止中断的操作以外,保存目前 CPU 的中断位信息*/
local_irq_save(flags)
local_irq_restore(flags)
/*只禁止中断的底半部*/
local_bh_disable()
local_bh_enable()
原子操作
1.设置原子变量的值
void atomic_set(atomic_t *v, int i); //设置原子变量的值为 i
atomic_t v = ATOMIC_INIT(0); //定义原子变量 v 并初始化为 0
2.获取原子变量的值
atomic_read(atomic_t *v); //返回原子变量的值
3.原子变量加/减
void atomic_add(int i, atomic_t *v); //原子变量增加 i
void atomic_sub(int i, atomic_t *v); //原子变量减少 i
4.原子变量自增/自减
void atomic_inc(atomic_t *v); //原子变量增加 1
void atomic_dec(atomic_t *v); //原子变量减少 1
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);
上述操作对原子变量执行自增、自减和减操作后(注意没有加)测试其是否为 0,为 0 则返回 true,否则返回 false。
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);
上述操作对原子变量进行加/减和自增/自减操作,并返回新的值。
static atomic_t xxx_available = ATOMIC_INIT(1); /*定义原子变量,赋值为1*/ static int xxx_open(struct inode *inode, struct file *filp) { ... if (!atomic_dec_and_test(&xxx_available)) /*测试值为0则返回true否则为false*/ { atomic_inc(&xxx_available); return - EBUSY; /*已经打开*/ } ... return 0; /* 成功 */ } static int xxx_release(struct inode *inode, struct file *filp) { atomic_inc(&xxx_available); /* 释放设备 */ return 0; }
自旋锁
spinlock_t lock; /*定义*/
spin_lock_init(&lock); /*初始化*/
spin_lock (&lock) ; /*获取自旋锁,保护临界区*/
....../*临界区*/
spin_unlock (&lock) ; /*解锁*/
标签:
原文地址:http://www.cnblogs.com/mage-sun/p/4789722.html