我在这里看到了几个关于 例外情况, ,其中一些暗示 中断作为异常, ,但没有人明确说明其中的联系。

  • 什么是中断?

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

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

有帮助吗?

解决方案

中断是由硬件或特定CPU指令产生的CPU信号。这些会导致执行中断处理程序。来自 I/O 硬件的 I/O 信号等事物会产生中断。

异常可以被认为是中断的软件版本,它只影响其进程。

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

其他提示

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

其他外设如定时器、USB 控制器等。还将根据某些外部事件生成中断。

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

不幸的是,关于异常的问题的答案不太清楚——本页的其他答案中列出了 3 种不同的含义。

Ron Savage 的答案涉及软件构造。这纯粹是应用程序级别的异常,其中一段代码能够指示可以被其他代码段检测到的错误。这里根本不涉及硬件。

然后是任务所看到的异常。这是一个操作系统级别的构造,用于在执行非法操作(例如除以 0、非法访问内存等)时终止任务。

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

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

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

中断表明处理器内核外部的某些事情需要它的关注。它中断程序的正常流程,执行中断服务例程(ISR),并且通常返回到中断发生之前的位置。

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

定义异常有点棘手,因为它可能具有三个层次的含义:

硬件异常

某些处理器(例如 PowerPC)定义异常来指示发生了某种异常情况:系统重置、无效地址、某些虚拟地址转换缓存未命中等...

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

操作系统异常

一些硬件异常将由操作系统处理。例如,您的程序访问无效内存。这会导致硬件异常。操作系统有一个针对该异常的处理程序,并且操作系统很可能会发送一个 信号 您的应用程序(例如 SIGSEGV)表示存在问题。

如果您的程序安装了信号处理程序,则信号处理程序将运行并有望处理这种情况。如果没有信号处理程序,程序可能会被终止或挂起。

我认为 Windows 的结构化异常处理程序 (SEH) 就是这种类型的异常。

软件异常

Java、C++ 和 C# 等一些语言具有软件异常的概念,该语言提供对不可预见或异常情况的处理 与程序的运行有关. 。在这种情况下,代码中的某个点会引发异常,并且程序执行堆栈上较高的一些代码将“捕获”异常并执行。这就是 try/catch 块的作用。

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

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

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

因此,假设我编写了一个简单的 C 程序,可以不间断地计算所有数字、斐波那契数列或其他内容。或者甚至更好:除了在 while(1) 循环内旋转之外什么也不做。系统上的其他进程如何获得运行的机会?如果没有发生任何事情导致中断怎么办?

答案是你有一个不断中断的定时器设备。它可以防止旋转过程破坏整个系统。尽管我会注意到中断处理程序会禁用中断,因此如果您执行无限期阻塞的操作,则可能会导致整个系统崩溃。

例外

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

打断

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

中断始终是例外,即使是有意为之。中断可能表明:

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

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

陷阱

就中断而言,常见的陷阱是竞争条件。例如,您可能有一个定期增加全局实时时钟的中断。在 32 位机器上时钟可能是 64 位。

如果程序正在读取时钟,并获取第一个 32 位字,则会发生中断,一旦中断处理程序退出,该进程就会获取第二个 32 位字,并且数据将不一致 - 这两个字可能不同步。如果您尝试使用互斥体或信号量来锁定进程中的变量,则中断将挂起等待锁定并停止系统(死锁),除非处理程序和使用数据的进程都非常仔细地编写。编写中断时很容易遇到麻烦。

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

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

-亚当

中断预计会定期发生(尽管有时不定期发生)。他们 打断 CPU,因为刚刚发生了一些重要的事情,需要立即处理。

例外情况应该是 例外情况 遵守规则;这些是由软件抛出的,因为发生了意外的事情,这是你尝试对此采取措施的机会,或者至少优雅地崩溃。

当您谈论中断和异常时,您通常谈论的是硬件级代码,中断和异常通常部分由硬件实现,部分由软件实现。

中断是硬件中的事件(或在汇编中手动触发),与可用于处理中断事件的处理程序向量相关联,无论是 IO 完成、IO 错误(磁盘内存故障)、IO 事件(鼠标移动)例如)。当一些意外中断发生时,中断常常会引起异常。

异常是指意外的行为,通常在使用硬件时,这些行为来自中断,并在软件中使用中断处理程序单独处理。我们所看到的编程语言几乎总是将其伪装成某种控制结构。

一般来说,中断是某种硬件实现的陷阱。您为特定中断(除以 0、外设上的数据可用、定时器到期)注册一个处理程序,当该事件发生时,所有处理系统范围都会停止,您可以快速处理该中断,然后事情继续进行。这些通常实现在设备驱动程序或内核中。

例外是处理代码中错误的软件实现方式。您为特定(或一般)异常设置处理程序。当异常发生时,语言运行时将开始展开堆栈,直到到达该特定处理程序的处理程序。此时,您可以处理异常并继续或退出程序。

让事情变得简单...

当您处理完中断后,您(通常)会返回到被中断之前正在做的事情。

处理异常涉及丢弃当前正在处理的连续层,直到冒泡到可以处理(捕获)异常的程度。

在处理中断时,您可能决定抛出异常,但这并不意味着您必须将中断本身视为异常。异常不会“中断”(因为这意味着有可能返回到被中断之前正在做的事情);相反,它们会“中止”您当前活动(的某些子集)。

而且,正如已经多次提到的,中断通常是由硬件或用户等外部实体(例如鼠标单击或 CTRL-C 等击键)触发的,而异常是由检测到“问题”或“问题”的软件同步生成(抛出)的。特殊条件”。

中断基本上是硬件驱动的,例如您的打印机指示它“缺纸”或网卡指示它已失去连接。

异常只是程序中的错误情况,由 try / catch 块检测到。喜欢:

Try
   {
   ... various code steps that "throw exceptions" on error ...
   }
catch (exception e)
   {
   print 'Crap! Something bad happened.' + e.toString()
   }

这是捕获代码块中发生的“任何错误”的便捷方法,以便您可以以类似的方式处理它们。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top