28 | 异常和中断:程序出错了怎么办?
徐文浩
该思维导图由 AI 生成,仅供参考
过去这么多讲,我们的程序都是自动运行且正常运行的。自动运行的意思是说,我们的程序和指令都是一条条顺序执行,你不需要通过键盘或者网络给这个程序任何输入。正常运行是说,我们的程序都是能够正常执行下去的,没有遇到计算溢出之类的程序错误。
不过,现实的软件世界可没有这么简单。一方面,程序不仅是简单的执行指令,更多的还需要和外部的输入输出打交道。另一方面,程序在执行过程中,还会遇到各种异常情况,比如除以 0、溢出,甚至我们自己也可以让程序抛出异常。
那这一讲,我就带你来看看,如果遇到这些情况,计算机是怎么运转的,也就是说,计算机究竟是如何处理异常的。
异常:硬件、系统和应用的组合拳
一提到计算机当中的异常(Exception),可能你的第一反应就是 C++ 或者 Java 中的 Exception。不过我们今天讲的,并不是这些软件开发过程中遇到的“软件异常”,而是和硬件、系统相关的“硬件异常”。
当然,“软件异常”和“硬件异常”并不是实际业界使用的专有名词,只是我为了方便给你说明,和 C++、Java 中软件抛出的 Exception 进行的人为区分,你明白这个意思就好。
尽管,这里我把这些硬件和系统相关的异常,叫作“硬件异常”。但是,实际上,这些异常,既有来自硬件的,也有来自软件层面的。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
计算机异常处理流程是计算机系统中的重要组成部分,包括硬件异常和软件异常。异常处理由硬件和软件共同完成,包括异常代码的分配、异常表的建立和异常处理程序的调用。无论是异步的中断还是同步的陷阱和故障,都采用相同的处理流程。文章通过实际应用举例,如Java中的异常处理程序和线程池的异常处理,帮助读者了解计算机异常处理的基本概念和流程。在实际处理异常之前,计算机需要先进行“保留现场”的操作,并在异常处理完成后重新回到之前执行的指令序列。异常处理过程类似于两个独立进程在CPU层面的切换,称之为上下文切换。推荐阅读《深入理解计算机系统》的第8章“异常控制流”部分,深入讲解异常和中断。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入浅出计算机组成原理》,新⼈⾸单¥68
《深入浅出计算机组成原理》,新⼈⾸单¥68
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(30)
- 最新
- 精选
- -_-|||文中“而是更像两个不同的独立进程之间在 CPU 层面的切换,所以这个过程我们称之为上下文切换(Context Switch)。”,那么,上下文就是运行在cpu层面的一个独立的进程?
作者回复: -_-_aaa同学, 你好,“上下文Context”并不是指具体的进程,而是可以理解为正在执行的进程所使用的各种“信息”,比如当时的寄存器,栈里面的各种数据和元数据。
2020-01-1624 - 沧海一粟有个疑问,软件层面的错误可以通过捕获-处理这样的流程解决。但是硬件难道永远不会出错吗,比如门电路输出有误,电压不足...等外部因素。换句话说 cpu计算的结果一定是正确的吗?
作者回复: 不是,所以实际的CPU要复杂很多啊,会有校验电路,纠错码等等。 另外,Intel历史上出现过设计错误导致特定浮点数计算出错,CPU召回过。
2023-03-29归属地:北京1 - Pennlinux内核中有软中断和硬中断的说法。比如网卡收包时,硬中断对应的概念是中断,即网卡利用信号“告知”CPU有包到来,CPU执行中断向量对应的处理程序,即收到的包拷贝到计算机的内存,然后“通知”软中断有任务需要处理,中断处理程序返回;软中断是一个内核级别的进程(线程),没有对应到本次课程的概念,用于处理硬中断余下的工作,比如网卡收的包需要向上送给协议栈处理。2019-07-07171
- 逆舟网上搜到的思考题答案,分享给大家: 硬中断由与系统相连的外设(比如网卡、硬盘)自动产生的。主要是用来通知操作系统系统外设状态的变化。 软中断是一组静态定义的下半部分接口,可以在所有的处理器上同时执行,即使两个类型相同也可以。但是一个软中断不会抢占另外的一个软中断,唯一可以抢占软中断的硬中断。 为了满足实时系统的要求,中断处理应该越快越好。编写驱动程序的时候,一个中断产生之后,内核在中断处理函数中可能需要完成很多工作。但是中断处理函数的处理是关闭了中断的。也就是说在响应中断时,系统不能再次响应外部的其它中断。这样的后果会造成有可能丢失外部中断。于是,linux内核设计出了一种架构,中断函数需要处理的任务分为两部分,一部分在中断处理函数中执行,这时系统关闭中断。另外一部分在软件中断中执行,这个时候开启中断,系统可以响应外部中断。 Linux为了实现这个特点,当中断发生的时候硬中断处理那些短时间,就可以完成的工作,而将那些处理事件比较长的工作,放到中断之后来完成,也就是软中断(softirq)来完成。2020-05-2930
- 陆离硬中断类似键鼠,网卡这些外接设备发出的中断请求,同比与上文的中断。 软中断类似程序内部IO的操作,由程序内部发出中断请求,同比上文的陷阱。2019-06-2827
- 栋能有点疑问,文中说“故障异常经异常处理程序处理之后会回到故障发生的指令位置,并再执行一次”,并还举例说加法溢出是故障异常,既然按这例子讲,难道再加一次就不会异常了吗?这可能会无限陷入故障异常的死胡同?2019-07-0646
- 陈小狮老师,请问java语言中的try..catch翻译成机器语言时是不是就是向异常表中注册了异常码? 另外,开发规范中说try..catch不要写在for循环里面,是不是因为以下两点?: 1.for循环里try..catch会导致多次注册异常表? 2.一旦for循环里面的代码发生异常,如果try..catch写在for循环里面,在执行catch异常处理前会发生[保存现场+上下文切换],catch异常处理完成之后上下文切换回来,继续执行for循环里的代码通常情况下可能会再次引发异常处理。而如果放在for循环外层,一旦发生异常,异常处理完毕,则会继续执行后面的代码逻辑。 望解答,谢谢老师!2020-09-0944
- 风这一讲,我给你讲了计算机里的“异常”处理流程。这里的异常可以分成中断、陷阱、故障、中止这样四种情况。这四种异常,分别对应着 I/O 设备的输入、程序主动触发的状态切换、异常情况下的程序出错以及出错之后无可挽回的退出程序。 当 CPU 遭遇了异常的时候,计算机就需要有相应的应对措施。CPU 会通过“查表法”来解决这个问题。在硬件层面和操作系统层面,各自定义了所有 CPU 可能会遇到的异常代码,并且通过这个异常代码,在异常表里面查询相应的异常处理程序。在捕捉异常的时候,我们的硬件 CPU 在进行相应的操作,而在处理异常层面,则是由作为软件的异常处理程序进行相应的操作。 而在实际处理异常之前,计算机需要先去做一个“保留现场”的操作。有了这个操作,我们才能在异常处理完成之后,重新回到之前执行的指令序列里面来。这个保留现场的操作,和我们之前讲解指令的函数调用很像。但是,因为“异常”和函数调用有一个很大的不同,那就是它的发生时间。函数调用的压栈操作我们在写程序的时候完全能够知道,而“异常”发生的时间却很不确定。所以,“异常”发生的时候,我们称之为发生了一次“上下文切换”(Context Switch)。这个时候,除了普通需要压栈的数据外,计算机还需要把所有寄存器信息都存储到栈里面去。2020-10-232
- 程序员花卷软中断,顾名思义,就是程序在执行的过程中所发生的异常,对应的是异步 硬中断,顾名思义,就是程序的异常来自于外部的系统,而不是正在执行的程序,对应的是同步2019-12-2012
- WL老师请问一下, 是不是无论哪种异常发生都会有一次上下文切换?2019-06-282
收起评论