如何解决并发导致的竞态问题

1. 中断屏蔽

相关函数

local_irq_disable()

local_irq_enable()

local_irq_save(flags)

local_irq_restore(flags)

local_bh_disable()

local_bh_enable()

模板

local_irq_disable();

//critical  section  临界区

local_irq_enable()

例程

void s3c2410_gpio_setpin(unsigned int pin, unsigend int to)

{

void __iomem *base=s3c24xx_GPIO_BASE(pin);

unsigned long offs=s3c2410_GPIO_OFFSET(pin);

unsigned long flags;

unsigned long dat;

local_irq_save(flags);

dat=__raw_read(base+0x04)

...

__raw_write(dat,base+0x04)

local_irq_restore(flags);

}

2. 信号量(semaphore)

信号量本身是一个整数值,可以大于1,

一对操作函数通常称为P和V

进入临界区(P)

      相关信号量上调P

      如果信号量>0,该值减一,进程继续

      如果信号量=0,进程等待,直到其它释放信号量

 退出临界区(V)

      信号量的解锁通过调用V完成

      该函数增加信号量的值

      必要的时候唤醒等待的进程

信号量与互斥体区别

信号量的值可以大于1, 而互斥体值只能为0或者1


初始化信号量

void sema_init(struct semaphore *sem,int val)

初始化静态互斥量

DECLARE_MUTEX(name)   //初始化为1

DECLARE_MUTEX_LOCKED(name)  //初始化为0

初始化动态互斥量

void init_MUTEX(name)   //初始化为1

void init_MUTEX_LOCKED(name)  //初始化为0

获取信号量

void down(struct semaphore *sem)//减小信号量的值,如果不能获得就一直等待

int down_interruptible(struct semaphore *sem)//完成和down一样的工作,但是操作是可以中断的

int down_trylock(struct semaphore *sem)  //永远不会休眠,如果信号量在调用时不可获得,就会立即返回一个非零值

释放信号量

void up(struct semaphore *sem)


使用信号量模板

DECLARE_MUTEX(sem)  //初始化为1

if(down_interruptible(&sem))

{

}

//critical section

up(&sem);

3. 完成量completion

静态初始化             DECLARE_COMPLETION(xxx_completion)    //   

动态创建                struct completion  xxx_completion;//创建一个完成量

                             init_completion(&xxx_completion)

等待完成量,没有完成之前,当前进程阻塞

void  wait_for_completion(struct  completion  *)

触发完成,唤醒一个等待进程

void   complete(struct  completion  *c)//唤醒一个等待线程

void  complete_all(struct  completion  *c)//唤醒所有等待线程

使用示例

DECLARE_COMPLETION(xxx_comp)

ssize_t  complete_read( struct file *file , char __user *buf, size_t count, lofft_t *pos)

{

         wait_for_completion(&xxx_comp);

         return 0;

}

ssize_t  complete_write( struct file *file , char __user *buf, size_t count, lofft_t *pos)

{

           completion(&xxx_comp);

           return 0;

}

4. 自旋锁

自旋锁是一个互斥设备

如果锁被其它设备获得,则代码进入忙循环,则代码进入忙循环并重复检查这个锁。

自旋锁和信号量的区别:

自旋锁是进入忙循环,即进程不阻塞,不退出,一直在while循环。而信号量是进程阻塞。

初始化自旋锁

spinlock_t  xxx_lock=SPIN_LOCK_UNCLKED;

void  spin_lock_init(spinlock_t  *lock);

锁定函数

void  spin_lock(spinlock_t  *lock)

获得自旋锁之前禁止中断(包括软件中断和硬件中断)

void  spin_lock_irq(spinlock_t  *lock)

获得自旋锁之前禁止中断(包括软件中断和硬件中断),中断状态保存在状态字flags中

void  spin_lock_irqsave(spinlock_t  *lock,  unsigned long flags)

获得自旋锁之前禁止软件中断,硬件中断保持打卡

void  spin_lock_bh(spinlock_t  *lock)

释放自旋锁

void  spin_unlock(spinlock_t  *lock)

void  spin_unlock_irqsave(spinlock_t  *lock,  unsigned long flags)

void  spin_unlock_irqsave(spinlock_t  *lock,  unsigned long flags)

void  spin_unlock_bh(spinlock_t  *lock)

自旋锁模板

spinlock_t  lock;

void  spin_lock_init(spinlock_t  &lock);

spin_lock(&lock)

//critical  section

spin_unlock(&lock)

5. 原子操作

http://www.jianshu.com/writer#/notebooks/917048/notes/1679174

你可能感兴趣的:(如何解决并发导致的竞态问题)