设为首页 收藏本站
查看: 537|回复: 0

[经验分享] Linux 开关中断系列函数探究

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-8-5 09:34:13 | 显示全部楼层 |阅读模式
Linux 开关中断系列函数探究
中断与锁
中断是Linux响应异步事件的一种方式,区别于陷阱、异常指令和出错等在指令执行完后产生的异常,它往往发生在处理器的外部,通常由外设触发,可以在指令执行完成的瞬间产生,也可能在指令执行的过程中产生,因而不可预测。从外设的角度看,中断是设备请求CPU响应的方式;而从调度的视角来看,中断是驱动系统心跳和调度的手段。而为了实现同步互斥机制,内核还基于处理器提供的原子指令实现了锁的机制,在进入临界段时需要上锁,而在退出时需要解锁,这样就保证了其他处理器不会也进入临界区。通过关本地中断,保重了当前运行的处理器不会再去执行其他内核线程,而是沿着当前上下文继续执行下去;而在临界段之前上锁,则防止其他处理器也执行即将要被执行的代码。那么在什么时候需要上锁,什么时候要关中断,什么时候二者都需要呢?下文结合Linux内核已经提供的几组相关函数进行了分析。
三组相关函数
Spin_lock 与spin_unlock
Spin_lock() 与 spin_unlock(),顾名思义,是内核提供的分别上锁和解锁的函数,值得一提的是这组函数在单处理器系统中,都退化成空操作,因为单处理器系统上只有一个处理器,所以任何当前正在执行的临界段,不可能被其他处理器再次进入。
Spin_lock_irq与spin_unlock_irq
与上面的spin_lock和spin_unlock这组函数的不同,spin_lock_irq()在执行的过程中,会先关本地中断,然后上锁;spin_unlock_irq()相反,会先解锁,然后打开本地中断。注意这里两个函数是互逆对称的操作过程。读者可以思考一下,spin_lock_irq()先上锁后关中断是否可以?答案是不可以,否则对应的spin_unlock_irq()执行的顺序就是开中断先然后解锁,在解锁和开中断的瞬间,如果有同一中断再被当前CPU响应,它就会再次调用spin_lock_irq(),里面先执行spin_lock(),可是这时该锁已经被它上次申请,并且没有来得及释放,这样它就会译制在这里死等。虽然它还可以响应其他类型的中端请求,但是该CPU无法再正确处理当前的中断类型。用户将会看到对应的设备好像停止了工作。
Spin_lock_irqsave 与spin_unlock_irqrestore
Spin_lock_irqsave()与spin_unlock_irqsrestore()除了分别包含spin_lock_irq()和spin_unlock_irq()所执行的所有操作之外,还会分别保存中断使能与否的状态、恢复中断使能的状态。因为有的中断可以以嵌套的方式执行,当前的中端可能正是嵌套进入的,这种情况下在unlockspin 锁后,内核不能贸然使能本地中断,而应恢复之前的中断使能状态,否则相当于在嵌套中断返回之前提前执行了本地中断使能的工作。这组函数具体的伪码如下:
Spin_lock_irqrestore()
{
…………
Save_local_irq_state(&flag);
Local_irq_disable()
Spin_lock();

…………
}

Spin_unlock_irqrestore()
{
Spin_unlock()
Restore_local_irq_state(flag);
Enable_local_irq()
}
使用场景对比
通过上面描述的对比可以看到,三组函数既有共同的地方,那就是上锁和解锁,也有不同的地方,那就是关于中断是否关闭、是否保存。所实现功能的不同,也就决定了三组函数应用场景的不同,下表给出了对比和说明:
QQ截图20150805093359.png
总结
内核提供了看似差不多实则有不小差别的中断、自旋锁相关的函数,我们需要根据不同的应用场景和需求谨慎选择,否则很容易出现意想不到的问题。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-94289-1-1.html 上篇帖子: pure-ftp samba 下篇帖子: Linux下c编程rename函数导致的问题 Linux 开关
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表