http://blog.csdn.net/wangyunqian6/article/details/7331862
今天再看《嵌入式软件系统教程》((美)西蒙 著,陈向群 等译)
,里面讲到关中断会关了任务调度,作者没说原因,我也不知道为什么,所以查了查网络。
===============================================================
在这个网址http://www.hqwic.com/bbs/topic.aspx?topicid=11253上有一个讨论,我觉得很有道理。很明显观点是关了中断,只是禁止了抢占,但并没有禁止调度。
这样看来,那本书上的观点是不正确的??
把一些自认为很有道理的解释摘抄下来:
首先说明一下,引起调度(任务切换)的原因有两个: 1、任务主动进入了阻塞状态,就像2楼说的,调用了所谓的切换函数。 2、中断,中断服务程序(isr)改变了任务状态,使某个比当前任务优先级高的任务进入了准备好(ready)状态,于是内核调用了切换函数。 这两个原因可以称为“同步方式调度”和“异步方式调度”。抢占的意义在于:如果高优先级任务进入准备好状态后,操作系统可以立即调度(任务切换),将高优先级任务投入运行。而这些动作对低优先级任务来说是完全透明的。 但是,谁?!使高优先级任务进入准备好状态,而又对低优先级任务透明呢?就是“中断”。 所以说,“抢占”是系统进行了“异步方式调度”的结果。既然关闭了中断,也就禁止了抢占。楼主,你想明白了吗? 在这里也要纠正一下3楼和5楼:“关了中断,就禁止了调度”这种说法不妥。关了中断,只是禁止了抢占,但并没有禁止调度啊。 |
正在运行的任务是所有就绪任务中优先级最高的,如果要运行其它优先级更高的任务,就只有发生了某些事件使得更高优先级的任务进入了就绪状态,而这些事件只有在两种情况下发生: 1. 中断改变了任务状态 2. 运行中的任务主动使优先级更高的任务进入就绪状态 2 相当于是主动放弃CPU占有权,所以说抢占是由中断引起的,是异步调度的结果(??这里逻辑有点问题。作者的意思可能是 :2是非抢占的,主动的,1是抢占的,被动的,所以说抢占是由中断引起的,是异步调度的结果。by imjacob) |
所以,你最开始的疑问:“关中断只是屏蔽了中断,并没有阻止任务切换,高优先级的任务任然可以抢占CPU并访问临界区和共享变量啊” 关了中断,就禁止了抢占,如果当前任务也没有进行主动调度,当然系统中也就不会出现比当前优先级更高的任务进入就绪了,也就谈不上去“抢占CPU并访问临界区和共享变量”了。(作者这里说加了条件“如果当前任务也没有进行主动调度”,那如果当前任务进行了主动调度会怎么样?我认为,若是在临界区中进行了主动调度,那么后果就是提问的人说的:“关中断只是屏蔽了中断,并没有阻止任务切换,高优先级的任务任然可以抢占CPU并访问临界区和共享变量”。by imjacob)
关 中 断 之 后, 任 何 外 部 事 件 都 不 能 打 扰 处 理 机 连 续 执 行 临 界 区 程 序。 如 果 临 界 区 程 序 本 身 并 不 包 含 使 它 的 进 程 转 变 为 封 锁 状 态 的 因 素, 那 (1) 它 不 能 用 于 多 处 理 机 系 统。 其 原 因 是: 由 于 该 系 统 中 的 多 个 处 理 机 都 有 其 各 自 的 中 断 开 关, 因 此 一 个 处 理 机 并 不 能 阻 止 在 其 它 处 理 机 上 运 行 的 进 程 进 入 同 类 临 界 区。 (2) 在 临 界 区 中 如 果 包 含 有 使 执 行 它 的 进 程 有 可 能 进 入 封 锁 状 态 的 因 素, 则 也 不 能 使 用 这 种 方 法。 因 为 在 该 进 程 进 入 封 锁 状 态 后, 系 统 将 调 度 另 一 进 程 使 用 处 理 机, 如 果 需 要, 该 进 (3) 如 果 临 界 区 比 较 长, 则 本 法 会 降 低 中 断 响 应 速 度。 (4) 这 是 一 把 锁 处 理 各 类 临 界 区, 不 必 要 地 扩 大 了 互 斥 范 围。 |
“为什么关中断开中断可以作为互斥条件,而且是最粗暴的方式呢?”
按上面的解释,开关中断是可以作为互斥条件的,但的确很粗暴。众所周知,嵌入式实时操作系统最关键的性能指标之一便是中断响应时间。中断响应时间越短,实时性就越好。但很多嵌入式操作系统(包括uCos在内)的中断响应时间都比较长。原因就是在这些操作系统中大量使用了关中断这种“粗暴”的方式(OS_ENTER_CRITICAL),你可以看看uCos, FreeRTOS等操作系统的源码,这样的写法比比皆是。当然,不用OS_ENTER_CRITICAL是不可能的,那会造成数据混乱,这是它们的系统结构所决定的。
如果能保证在中断处理中不去写共享数据(包括可能改变共享数据的系统调用),就可以不用关中断了,但这需要改变系统结构,把中断服务分为两个部分,这就是所谓的“Top half 和 Bottom half”。如果想了解具体,你可以去网上查查。应用这种技术的操作系统有Linux, Windows, eCos等。 |
|
后记:
另外在查网络的时候,还看到一本中国人的书<操作系统教程>(http://books.google.cn/books?id=X8lmMtog0XcC&pg=PT59&lpg=PT59&dq=%E5%85%B3%E4%B8%AD%E6%96%AD+%E4%BA%92%E6%96%A5&source=bl&ots=GwX4qh0hM0&sig=j1ieBs1RvU-bTpkddC4OyxoneTc&hl=zh-CN&sa=X&oi=book_result&resnum=2&ct=result)
3.2.2 硬件方法中写:“ 因为cpu只在发生中断时引起进程切换,这样禁止中断就能保证当前运行进程将临界区代码顺利执行完,从而保证了互斥的正确实现。”显然也是错的。我们可以当作练习把它改正了。哈哈。