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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,585评论 4 365
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,923评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,314评论 0 248
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,346评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,718评论 3 291
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,828评论 1 223
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,020评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,758评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,486评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,722评论 2 251
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,196评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,546评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,211评论 3 240
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,132评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,916评论 0 200
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,904评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,758评论 2 274

推荐阅读更多精彩内容

  • 1 临界区 1.1简介 在早期计算机系统中,只有一个任务进程在执行,并不存在资源的共享与竞争。随着技术和需求的飞速...
    Fly晴天里Fly阅读 8,941评论 2 13
  • 内核里处理的竞态主要通过以下方法处理: 信号量(互斥量)、自旋锁、读写信号量、读写自旋锁、等待队列、完成量。 信号...
    Lmmmmbbb阅读 544评论 0 0
  • 线程安全是怎么产生的 常见比如线程内操作了一个线程外的非线程安全变量,这个时候一定要考虑线程安全和同步。 - (v...
    幽城88阅读 615评论 0 0
  • POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API。线程同步(Thre...
    北辰青阅读 986评论 0 1
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,641评论 0 9