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

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

作者: 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

相关文章

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

    1. 中断屏蔽 相关函数 local_irq_disable() local_irq_enable() local...

  • Linux驱动之并发控制

    Linux设备驱动中必须解决的一个问题是多个进程对共享资源的并发访问,并发的访问会导致竞态,即使是经验丰富的驱动工...

  • linux的并发和竞态管理

    1 并发和竞态产生的原因 并发是操作系统编程中的核心问题之一。我们必须要能解决对共享资源的并发访问。 并发产生资源...

  • 【2020-02-24】leetcode 多线程

    多线程---并发 并发主要为多任务情况设计:竞态条件:由于多进程之间的竞争执行,导致程序未按照期望的顺序输出。死锁...

  • 数据库事务--事务隔离级别

    数据库里关于事务的并发问题,也叫做竞态条件(race condition)。它是描述并发事务中,一个事务需要读取另...

  • 并发与竞态

    自旋锁 自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是 否该自旋锁的保持者...

  • [读书笔记]并发和竞态(第五章)

    综述 并发问题是编程中经常遇到的难题,我们需要学会针对并发产生的竞态进行编程 一、信号量和互斥体 Linux上信号...

  • 自旋锁的原理及使用

    自旋锁的使用场景 当多个执行单元同时、并行 地执行,并且并发的执行单元对共享资源进行访问,则会导致竞态。这些执行单...

  • 互斥锁,解决原子性问题

    并发编程有3个源头性问题:缓存导致的可见性问题,编译优化导致的有序性问题,以及线程切换导致的原子性问题。解决可见性...

  • 用不变对象解决竞态问题

    不可变对象 所有并发问题都是由于多个线程同时访问对象的某个可变属性引起的, 如果对象是不可变的, 那么所有的并发问...

网友评论

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

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