微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Linux内核开发之并发控制(一)

Linux内核开发之并发控制(一)

时间:12-19 来源:互联网 点击:

“小涛,你说十一黄金周,火车站,飞机场那些售票系统咋没一个宕掉的呢。你不宕掉也没关系,来两个卖错票的,说不定哥就去上海看世博,去北京看青梅竹马的表妹了…”小王抱怨道。

“晕死..哥鄙视你,你说都老大不小的人了,怎么脑子里天天都是MM之类的事了,能不能有点男子气概啊..”。

“靠,能跟你比啊,你是饱汉不知饿汉饥,要是像你一样十一和…”

"嗯,啊,哼哼.."没等他说完,我赶忙塞了双臭袜子(哪天的也记不住了)。“得得,I 服了 you,ok”。

“不过话说回来,小王,你说的还真是个问题,想想这样的问题,你和GF两个要去西湖看白娘子,偏偏遇到老天跟你过不去,就只剩下一张票了,你和GF两个谁去…“

"不是吧,我这命苦,好不容易有个GF,应该不会出现的,呵呵,如果出现…那好办,我和她商量好,咱们一起在晚上12:00一起买票,这样我们两边的售票员怎么看都各自有一张票,我们两个就可以一起了"小王狡黠的笑着。

“笨,我一口一个盐水喷死你,分明一张票,你们两个同一个时间去两个不同的售票点去买,它还是一张票,怎么可能说去两个不同地方,两个售票员都看到有一张票,然后就把这唯一的一张同时卖给了你们两个人”我打断到。"算了,看在室友兼我的最忠实狗仔队员的身份,哥就传授一招只传MM的绝学----Linux设备驱动程序之并发控制"。

听说过并发没,那你肯定听说过竞争,比如竞争上岗,还有你最熟悉的追MM,这也是竞争。那么

并发(concurrency)就是说多个执行单元同时,并行被执行,这多个单元却不巧要同时访问一些资源。这其中要分三种情况:

  

正所谓:道高一尺,魔高一丈,你孙悟空有72变,人家二郎神还有73变不是。有问题,没关系,找小涛哥不是..呵呵。现在就教你几招以备不时只需:

大家不是要竞争吗,那好,总体原则就是不让你竞争:保证一个执行单元在访问共享资源的时候,其他的执行单元被禁止访问,将竞争扼杀在萌芽状态。这就是传说中的对共享资源的互斥访问。

出招表一:中断屏蔽(可以保证正在执行的内核执行路径不被中断处理程序抢占,由于Linux内核的进程调度都依赖中断来实现,内核抢占进程之间的竞态就不存在了)

使用方法: local_irq_disable() //屏蔽中断 说明:local_irq_disable()和local_irq_enable()都只能禁止和使能本CPU内的中断

…. 并不能解决SMP多CPU引发的竞争。

critical section //临界区

….

local_irq_enable() //开中断

与local_irq_disable()不同,local_irq_save(flags)除了进行禁止中断操作以外,还保证目前CPU的中断位信息,local_irq_save(flags)进行相反的操作。

致命弱点: 由于Linux系统的异步I/O,进程调度等很多重要操作都依赖于中断,在屏蔽中断期间所有的中断都无法处理,因此长时间屏蔽中断是很危险的,有可能造

成数据丢失甚至系统奔溃。

出招表二:原子操作(忘了是物理还是化学老师拉着我的手说:原子是最小的,不能再分的东西.看多形象,执行过程不能被别的代码路径中断的操作就是原子操作,还

想跟我竞争,门都没有)。 分为整形原子和位原子操作。

使用方法一:整形原子操作

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);//这些操作对原子变量执行自增,自减,减操作后测试是否为0,是返回true,否则返回false

int atomic_dec_and_test(atomic_t *v);

int atomic_sub_and_test(int i, atomic_t *v);

6)操作并返回

int atomic_add_return(int i,atomic_t *v); //这些操作对原子变量进行对应操作,并返回新的值。

int atomic_sub_return(int i, atomic_t *v);

int atomic_inc_return(atomic *v);

int atomic_dec_return(atomic_t *v);

使用方法二:位原子操作。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top