中断和例外

Ada*_*vis 20 terminology exception interrupt

我在这里看到了几个关于异常的问题,其中一些暗示将中断视为异常,但没有一个能使连接清晰.

  • 什么是中断?

  • 什么是例外?(请解释您知道的每种语言的例外情况,因为存在一些差异)

  • 什么是异常中断,反之亦然?

And*_*mbe 21

您的处理器将有许多外部中断引脚.通常,这些引脚连接到硬件,用于指示何时发生某些外部事件.例如,如果使用串行端口,则UART将升高引脚,该引脚连接到处理器上的一个中断引脚,以指示已接收到一个字节.

其他外设如定时器,USB控制器等也会在某些外部事件的基础上产生中断.

当处理器在其中一个外部中断引脚上接收到信号时,它将立即跳转到存储器中的某个指定位置并开始执行.执行的代码通常称为ISR或中断服务例程.除非您正在实施驱动程序或进行某种类型的嵌入式软件,否则您不可能遇到ISR.

不幸的是,关于例外的问题的答案有点不太清楚 - 本页的其他答案中列出了3种不同的含义.

Ron Savage的回答是指软件构造.这纯粹是一个应用程序级异常,其中一段代码能够指示一些其他代码可以检测到的错误.这里根本没有硬件参与.

然后是任务所见的异常.这是一个操作系统级别构造,用于在任务非法时执行任务 - 例如除以0,非法访问内存等.

第三,有硬件例外.在行为方面,它与中断相同,因为处理器将立即跳转到某个指定的存储器位置并开始执行.异常与中断不同的是异常是由处理器检测到的某些非法活动引起的.例如,处理器上的MMU将检测非法内存访问并导致异常.这些硬件异常是操作系统执行清理任务的初始触发器(如上段所述).


zvr*_*rba 11

中断由CPU外部的设备(定时器滴答,磁盘操作完成,网络数据包到达等)生成,并且与程序执行异步.异常与程序执行同步(例如,除以零,访问无效地址).

除非您的程序在没有操作系统的情况下执行(或者您正在开发操作系统),否则它将永远不会看到原始异常/中断.它们被操作系统捕获并由它处理(中断),或者在被反射回用户程序之前转换为其他形式(例如UNIX上的信号,Windows上的结构化异常处理(SEH)),它有可能处理它.


Tra*_*ony 8

中断是由硬件或特定CPU指令生成的CPU信号.这些导致中断处理程序被执行.诸如来自I/O硬件的I/O信号之类的事情会产生中断.

可以将异常视为中断的软件版本,仅影响其进程.

我不确定具体细节,但可以通过中断来实现例外.


Ben*_*oit 8

中断表明处理器核心外部的某些东西需要它的注意.它会中断程序的正常流程,执行中断服务程序(ISR)并通常返回到中断发生之前的位置.

这个基本主题有很多变化:中断可能由软件生成,另一个任务可能在ISR之后获得CPU等.关键是中断可以随时发生,原因是代码/ CPU 没有控制权.

一个例外有点难以定义,因为它可能有三个层次的含义:

硬件异常

某些处理器(例如PowerPC)定义异常以指示出现某种异常情况:系统重置,无效地址,某些虚拟地址转换高速缓存未命中等...

这些异常也用于实现断点和系统调用.在这种情况下,它们的行为几乎就像中断一样.

操作系统例外

一些硬件异常将由OS处理.例如,您的程序访问无效内存.这将导致硬件异常.操作系统具有该异常的处理程序,并且操作系统将向您的应用程序发送信号(例如,SIGSEGV),表示存在问题.

如果您的程序安装了信号处理程序,信号处理程序将运行并希望处理这种情况.如果您没有信号处理程序,则可以终止或暂停程序.

我会认为窗口的结构化异常处理程序(SEH)是这种类型的异常.

软件例外

Java,C++和C#等语言具有软件异常的概念,其中语言用于处理与程序操作相关的不可预见或异常情况.在这种情况下,代码中的某个点会引发异常,程序执行堆栈上的某些代码会"捕获"异常并执行.这就是try/catch块的功能.


Dan*_*ian 5

我将详细说明中断是什么,因为还有一个关键类型的中断没人处理过:计时器.

但首先,让我备份.当你得到一个中断时,你的中断处理程序(它位于内核空间中)会运行,这通常会禁用中断,查看任何未决的业务(处理刚刚到达网络的数据包,处理击键等)然后(记住我们) "此时仍然在内核中"确定下一个应该运行的进程(可能是同一个进程,可能是不同的进程,取决于调度程序)然后运行它.

在任何给定时间,只有一个进程在处理器上运行.当你使用多任务操作系统时,它在它们之间切换的方式称为上下文切换 - 基本上处理器的寄存器被转储到内存,流程传递到新进程,当进程完成时你上下文切换到某个东西其他.

所以,假设我写了一个简单的C程序,它可以计算所有数字,或Fibonacci序列,或其他不停止的东西.或者甚至更好:只做一次while(1)循环内部的旋转.系统上的其他进程如何运行?如果没有任何事情导致中断怎么办?

答案是你有一个不断打断的计时器设备.正是这使得整个系统不再需要一个旋转过程.虽然我会注意到中断处理程序禁用了中断,所以如果你做了无限制阻塞的事情,你可以取下整个系统.


Ada*_*vis 5

例外

例外情况是处理器执行不在其正常路径上的代码.这是正常操作的"例外",它基本上是通过代码和控制结构的线性移动.不同的语言支持各种类型的异常,通常用于在程序操作期间处理错误.

打断

中断是硬件级别的异常(通常).中断是处理器中的物理信号,它告诉CPU存储其当前状态并跳转到中断(或异常)处理程序代码.处理程序完成后,将恢复原始状态并继续处理.

中断始终是一个例外,即使它是预期的.中断可能表明:

  • 错误,例如内存访问冲突
  • 操作系统需要执行操作以支持正在运行的程序,例如软件中断或内存分页请求
  • 硬件设备需要注意,例如接收到的网络数据包或空的发送缓冲区

这些总是强制处理器暂停其当前活动以处理引发的异常,仅在中断处理程序完成后才恢复.

陷阱

在中断方面,常见的陷阱是竞争条件.例如,您可能有一个周期性地增加全局实时时钟的中断.32位机器上的时钟可能是64位.

如果程序正在读取时钟,并获得前32位字,那么中断发生,一旦中断处理程序退出进程获得第二个32位字,并且数据将是不连贯的 - 这两个字可能不同步.如果您尝试使用互斥锁或信号量来锁定进程中的变量,那么中断将等待锁定并暂停系统(死锁),除非处理程序和使用数据的进程都非常仔细地写入.写中断时很容易陷入困境.

可重入函数也是另一个问题.如果您正在程序代码中执行funcA,请执行也执行funcA的中断,由于共享变量(静态或堆变量,类等),可能会导致意外后果.您通常希望在中断处理程序中尽可能少地执行代码,并经常让它设置一个标志,以便进程可以在以后执行实际工作,而不必担心冲突.

在某些方面,这类似于为多处理器开发,并且是许多人仍然认为内核编程被认为是黑魔法的原因之一.

-亚当