美文网首页
如何解决并发导致的竞态问题

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

作者: three_eyelid | 来源:发表于2015-08-05 17:52 被阅读0次

    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

    相关文章

      网友评论

          本文标题:如何解决并发导致的竞态问题

          本文链接:https://www.haomeiwen.com/subject/wxzvqttx.html