- 1、本文档共14页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
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)操作并返回
文档评论(0)