Linux内核开发之并发控制(一)
“小涛,你说十一黄金周,火车站,飞机场那些售票系统咋没一个宕掉的呢。你不宕掉也没关系,来两个卖错票的,说不定哥就去上海看世博,去北京看青梅竹马的表妹了…”小王抱怨道。
“晕死..哥鄙视你,你说都老大不小的人了,怎么脑子里天天都是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);
使用方法二:位原子操作。
- REDIce-Linux--灵活的实时Linux内核(11-12)
- linux文件系统基础(02-09)
- Linux标准趋向统一(11-12)
- linux基础技术(02-09)
- LINUX的目录树(02-09)
- 在Windows下启动Linux(02-09)