【问题标题】:Why processes cannot preempt interrupts?为什么进程不能抢占中断?
【发布时间】:2015-03-29 09:32:20
【问题描述】:

我知道当中断发生时,运行的进程会被暂停,并调用中断服务程序。 current 指针指向被中断的进程,有人告诉我,当中断发生时,它不会链接到特定进程。所以我的问题是为什么只有另一个中断可以抢占现有的中断程序?

另外,当一个进程(p2)抢占另一个进程(p1)时,谁在调用schedule()方法?

【问题讨论】:

  • 无论schedule() 是什么,它很可能被定时器中断调用,比如p3。如果定时器中断的优先级高于您的p2,它将中断p2,并且也将被搁置。如果不是,则p3 无法启动,直到p2 完成,最终控制权将返回给p1
  • 谁告诉你当中断发生时它并没有链接到特定的进程?
  • @stdcall 取决于“中断”和“链接”的含义。硬件中断在执行时没有进程状态; Excel 重新计算可能会被 NIC 中断,该 NIC 表示 BitTorrent 客户端的网络读取完成。中断处理程序必须不对它中断的进程做出任何假设。我怀疑这是 OP 所暗示的。

标签: c linux kernel interrupt context-switch


【解决方案1】:

前两个答案都显示出对中断及其工作方式的一些重大误解

特别感兴趣,

对于我们通常使用的 CPU

(86x..、power PC、68xxx、ARM 等)

每个中断源都有一个优先级。

可悲的是,有一些 CPU,例如 68HC11,所有中断,除了复位中断和 NMI 中断,都具有相同的优先级,因此服务任何其他中断事件将阻塞所有其他中断(相同优先级)中断事件。

出于我们讨论的目的,较高优先级的中断事件可以/将中断较低优先级的中断处理程序。

(中断处理程序可以修改适当的硬件寄存器以禁用所有中断事件或仅禁用某些中断事件。甚至通过清除自己的中断挂起标志(通常是寄存器中的位)来启用较低优先级的中断

通常,调度程序由中断处理程序调用,

(或通过自愿放弃 CPU 的进程)

该中断通常是硬件计时器到期/重新加载并触发中断事件的结果。

中断实际上只是一个事件,该事件正在等待服务。

如果允许中断事件,例如作为当前未决的最高优先级中断,将导致 PC 寄存器加载相关中断处理程序的第一个地址。

将 PC 寄存器转移到中断处理程序的行为将(至少)将先前的 PC 寄存器值和状态寄存器压入堆栈。 (在某些 CPU 中,这些寄存器有一组特殊的保存区域,因此它们被推送到特殊区域而不是堆栈上。

从中断返回的动作,例如通过 RTI 指令,将“自动”导致先前的 PC 和状态寄存器值被恢复。

注意:从中断处理程序返回不会清除中断事件挂起指示,因此中断处理程序在退出前需要修改相应的寄存器,否则执行流程将立即重新进入中断处理程序。

中断处理程序必须在进入时推送它修改的任何其他寄存器,并在准备退出时恢复它们。

只有较低优先级的中断会被中断事件阻止,从而将 PC 转移到适当的中断处理程序。被阻止,而不是被禁用。

在某些 CPU(例如大多数 DSP)上,也存在可由指令执行触发的软件中断。 这通常被硬件中断处理程序用来在一定数量的数据被输入/保存到缓冲区后触发数据处理。这将 I/O 与处理分离,从而使硬件中断事件处理程序能够快速处理并及时处理数据

上述内容与 cmets 和其他答案的大部分内容相矛盾。然而,这些 cmets 和答案来自操作系统“用户”方面的误导性观点,而我通常在裸硬件上进行编程,因此对实际发生的情况非常熟悉。

【讨论】:

  • '该中断通常是硬件计时器到期/重新加载并触发中断事件的结果。' - 真的?磁盘、网卡、USB等驱动中断异常?
  • 非常感谢您提供上述详细信息!这对我来说非常清楚。我还有一个问题。你说'将PC寄存器转移到中断处理程序的行为将(至少)将先前的PC寄存器值和状态寄存器推入堆栈。 '。谁的堆栈?内核栈?前一个进程的堆栈?
【解决方案2】:

所以我的问题是为什么只有另一个中断可以抢占现有的 中断例程?

硬件中断通常会将处理器硬件置于所有中断都被禁用的中断状态。中断处理程序可以并且经常确实显式地重新启用更高优先级的中断。这样的中断然后可以抢占较低优先级的中断。这是唯一可以中断硬件中断的机制。

另外,当一个进程(p2)抢占另一个进程(p1)时,谁正在调用 schedule() 方法?

这在一定程度上取决于抢占是由已经运行的线程的系统调用发起的,还是由导致处理程序/驱动程序运行并随后进入内核以请求重新调度的硬件中断发起的。使用的确切机制(状态、堆栈等)取决于架构。

【讨论】:

  • 在中断处理程序中,我可以调用 schedule() 方法吗?如果是,会发生什么?我知道我不应该这样做,因为处理程序必须快速运行并且不能等待其他调用。
  • 操作系统内核是一个中断处理程序。
【解决方案3】:

关于您的第一个问题:在运行中断时,该处理器上的中断被禁用。因此,它不能被中断。

关于您的第二个问题:一个进程永远不会抢占另一个进程,它始终是操作系统这样做。操作系统定期调用调度程序例程,它决定接下来运行哪个进程。所以 p2 并没有说“我想现在运行”,它只是有一些属性,比如优先级、剩余时隙等,然后由操作系统决定 p2 是否应该现在运行。

【讨论】:

  • '操作系统定期调用调度程序例程' - 通常没有错,但实际上有点经济。调度程序可能由更改进程/线程状态的系统调用或由请求调度运行的硬件中断和驱动程序运行,您引用的计时器中断只是这些中断源之一,可以说是磁盘、NIC KB、鼠标、内存-管理驱动程序中断更重要。
  • '当中断运行时,该处理器上的中断被禁用'——是这样吗?我认为只有一条运行中断被禁用,如果发生另一个中断——前一个中断将被停止并处理新的中断(至少在 ARM 上,如果第二个中断具有更高的优先级)。阅读this
  • 看来你是对的。在this 补丁中更改了中断禁用行为。现在我们没有 fastslow 中断。所有中断都被视为快速,慢速中断必须实现为线程(或使用local_irq_enable_in_hardirq() 在ISR 中手动启用中断)。所以是的,在中断运行时所有中断都被禁用。详情here.
  • 是的,当一个中断运行时所有中断都被禁用,这就是处理器所做的,但是在中断处理程序中你可以重新启用其中的一些(不是当前正在运行的)
猜你喜欢
  • 1970-01-01
  • 2017-02-17
  • 2017-03-12
  • 2014-06-11
  • 2014-01-13
  • 1970-01-01
  • 2010-10-23
  • 2011-07-07
  • 1970-01-01
相关资源
最近更新 更多