关中断/禁调度/信号量/原子变量的区别和用法

 

 

有人问及关中断和保护全局变量的问题,还有人以为开中断时会导致cpu不停地查看有没有中断而变慢,我答及:关于中断使cpu变慢的问题:1、cpu的中断管理和指令执行(运算器)是两套硬件,他们互相独立又有关联。运算器忠实地执行由取指器取得的指令,而中断管理器是通过影响取指地址来使cpu执行中断处理程序的。
2、无论中断是否允许,运算器都按自己的节奏工作,无须花时间去查询是否由中断到达,因此,cpu在任何时候都不会因中断而变慢,中断只是使主程序看起来变慢了,只要没有有效中断发生,cpu执行主程序也不会变慢。
3、中断管理器则不断地探测是否有中断信号到达,若有且中断允许(即发生了有效中断),则保存当前执行状态信息,然后打断当前取指序列,强行转到特定地址(中断向量)取指令,整个过程运算器并不知道,它只是忠实地执行取指电路取得的指令。
        为保证正确访问临界数据区(共享资源)和正确执行临界代码段,操作系统需要使某些关键操作保持同步,操作系统一般提供“关中断、关调度、信号量”来用于线 程(进程)同步,还有些操作系统提供原子变量的方法,linux中广为人知的锁其实是用信号量实现的。那么,这么多的方法中,什么情况适用哪一种方法呢? 是有规律的。
1、原子变量
原子变量可以保证一个变量单次操作的正确性,其保护甚至比信号量还完善,信号量只能保护全局数据不被其他线程破坏,而原子变量能保证全局数据不被中断破坏。
example1:
int a;
int b,c;
a = a + b + c;
上述代码中,cpu对a有一个读、修改、写的过程,这个过程如果被打断,并在其他线程中修改了a值,执行结果将出现错误,而原子变量将保证不会发生这样的错误。 把上述代码改为:atomic_t a;
int b,c;
atmotic_add(&a ,   b + c);
原子变量能保证变量一次操作的原子性,并不能保证一系列操作的原子性,若把上述代码改为
example2:
atomic_t   a;
int b,c;
atmotic_add(&a ,   b ); //L1
atmotic_add(&a ,    c ); //L2
原子变量不能保证L1和L2两行程序间a不被其他线程修改,因此example2不一定能得到正确的结果。
2、信号量
        原子变量并非所有操作系统都会提供,但几乎所有操作系统都提供信号量机制,用于保护临界代码。信号量能设定并发访问次数限制n,够保证被信号量保护的代码 不会发生超过n次的并发访问,如果n=1,就是所谓的二值信号量,二值信号量禁止对被保护资源的任何并发访问。上述example2不能用原子变量保护, 但可以用信号量保护,改成:
获取信号量;
a = a + b; //L1
a = a + c; //L2
释放信号量;
当一个全局变量可能被多个线程操作时,或者有多个线程或进程需要使用独占资源时,就应该用信号量保护,注意,不能在中断处理程序中访问用信号量保护的变量。
3、关调度
关调度是一种比较粗暴的方式,关调度后,操作系统不会再进行线程上下文切换,而是专心执行一个线程,但是中断仍然开着。关调度可以起到替代信号量保护全局 变量的作用,但一般不这样用,太粗暴了。但是如果某一段代码的执行时间有要求,希望cpu全速执行不被打断,但又不希望关中断时,可用关调度的方法。注 意,从逻辑上,关调度能替换信号量,但不能替换原子变量。
4、关中断
关中断是最粗暴的一种方式,用于保证最严格的时序执行,比如某段代码要在IO上输出两个高精度脉冲,脉冲宽度2uS,间隔2uS,这种需求只能通过用精确 的指令延时来实现,延时过程中,如果被中断,或者发生线程切换,将不能正确输出脉冲。从逻辑上,前面所讲的三种保护,都可以用关中断实现,只是,太粗暴 了,软件不相信暴力!

 

 

 

 

阅读笔记:

1.第二条最后说不能在中断处理程序里面访问用信号量保护的变量,是因为对临界区的访问可以被中断打断,中断里面访问被保护的变量会使得信号量保护起不到作用。

2.第三条最后说关调度能够替换信号量,但是不能替换原子变量,是因为上面说过,原子变量可保证全局数据不被中断破坏,而关调度和信号量都做不到这一点。

3.关中断这种操作会导致系统对中断的响应延迟。

4.关中断与信号量进行互斥的区别:关了中断后,抢占是被关闭的,除非当前任务主动放权,否则调度是禁止的,那么该任务会一直运行直到开中断;而信号量保护了临界区,但是在临界区代码执行时cpu可能会被抢占,也就是临界区代码并不一定是一口气执行完的。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值