计算机如何处理异常

前言

大家好,我是jiantaoyab,这篇文章主要计算机究竟是如何处理异常的,异常可以分成中断、陷阱、故障、中止这样四种情况。这四种异常,分别对应着 I/O 设备的输入、程序主动触发的状态切换、异常情况下的程序出错以及出错之后无可挽回的退出程序

程序在实际的执行过程中,会遇到各种异常的情况,我们这里谈的是硬件的异常,不是我们写C++程序所抛出软件异常。比如,我们在硬件层面,当加法器进行两个数相加的时候,会遇到算术溢出;或者,你在玩游戏的时候,按下键盘发送了一个信号给到 CPU,CPU 要去执行一个现有流程之外的指令,这也是一个“异常”。
同样,来自软件层面的,比如我们的程序进行系统调用,发起一个读文件的请求。这样应用程序向系统调用发起请求的情况,一样是通过“异常”来实现的。

异常

关于异常,最有意思的一点就是,它其实是一个硬件和软件组合到一起的处理过程。异常的前半生,也就是异常的发生和捕捉,是在硬件层面完成的。但是异常的后半生,也就是说,异常的处理,其实是由软件来完成的

计算机会为每一种可能会发生的异常,分配一个异常代码(Exception Number)。有书会把异常代码叫作中断向量(Interrupt Vector)。

异常发生的时候,通常是 CPU 检测到了一个特殊的信号。比如,你按下键盘上的按键,输入设备就会给 CPU 发一个信号。或者,正在执行的指令发生了加法溢出。

同样,我们可以有一个进位溢出的信号。这些信号呢,在组成原理里面,我们一般叫作发生了一个事件(Event)。CPU 在检测到事件的时候,其实也就拿到了对应的异常代码。

这些异常代码里,I/O 发出的信号的异常代码,是由操作系统来分配的,也就是由软件来设定的。而像加法溢出这样的异常代码,则是由 CPU 预先分配好的,也就是由硬件来分配的。这又是另一个软件和硬件共同组合来处理异常的过程。

异常表

拿到异常代码之后,CPU 就会触发异常处理的流程。计算机在内存里,会保留一个异常表(Exception Table)。也有地方,把这个表叫作中断向量表(Interrupt Vector Table)。

异常表存放的是不同的异常代码对应的异常处理程序所在的地址

CPU 在拿到了异常码之后,会先把当前的程序执行的现场,保存到程序栈里面,然后根据异常码查询,找到对应的异常处理程序,最后把后续指令执行的指挥权,交给这个异常处理程序。

image-20240313181004402

日常进行的 Web 或者 App 开发,通常都是前后端分离的。前端的应用,会向后端发起 HTTP 的请求。当后端遇到了异常,通常会给到前端一个对应的错误代码。前端的应用根据这个错误代码,在应用层面去进行错误处理。在不能处理的时候,它会根据错误代码向用户显示错误信息

image-20240313181051476

中断

程序在执行到一半的时候,被打断了。这个打断执行的信号,来自于 CPU 外部的 I/O 设备。你在键盘上按下一个按键,就会对应触发一个相应的信号到达 CPU 里面。CPU 里面某个开关的值发生了变化,也就触发了一个中断类型的异常。

陷阱

是我们程序员“故意“主动触发的异常。就好像你在程序里面打了一个断点,这个断点就是设下的一个"陷阱"。当程序的指令执行到这个位置的时候,就掉到了这个陷阱当中。然后,对应的异常处理程序就会来处理这个"陷阱"当中的猎物

最常见的一类陷阱,发生在我们的应用程序调用系统调用的时候,也就是从程序的用户态切换到内核态的时候。在 Linux 下执行 time 指令,去查看一个程序运行实际花费的时间,里面有在用户态花费的时间(user time),也有在内核态发生的时间(system time)。

我们的应用程序通过系统调用去读取文件、创建进程,其实也是通过触发一次陷阱来进行的。这是因为,我们用户态的应用程序没有权限来做这些事情,需要把对应的流程转交给有权限的异常处理程序来进行。

故障

它和陷阱的区别在于,陷阱是我们开发程序的时候刻意触发的异常,而故障通常不是。比如,我们在程序执行的过程中,进行加法计算发生了溢出,其实就是故障类型的异常。这个异常不是我们在开发的时候计划内的,也一样需要有对应的异常处理程序去处理。

故障和陷阱、中断的一个重要区别是,故障在异常程序处理完成之后,仍然回来处理当前的指令,而不是去执行程序中的下一条指令。因为当前的指令因为故障的原因并没有成功执行完成

中止

与其说这是一种异常类型,不如说这是故障的一种特殊情况。当 CPU 遇到了故障,但是恢复不过来的时候,程序就不得不中止了

image-20240313181353883

在这四种异常里,中断异常的信号来自系统外部,而不是在程序自己执行的过程中,所以我们称之为“异步”类型的异常。

而陷阱、故障以及中止类型的异常,是在程序执行的过程中发生的,所以我们称之为“同步“类型的异常。

在处理异常的过程当中,无论是异步的中断,还是同步的陷阱和故障,我们都是采用同一套处理流程,也就是上面所说的,“保存现场、异常代码查询、异常处理程序调用“。而中止类型的异常,其实是在故障类型异常的一种特殊情况。当故障发生,但是我们发现没有异常处理程序能够处理这种异常的情况下,程序就不得不进入中止状态,也就是最终会退出当前的程序执行。

异常的处理

在实际的异常处理程序执行之前,CPU 需要去做一次“保存现场”的操作。

因为切换到异常处理程序的时候,其实就好像是去调用一个异常处理函数。指令的控制权被切换到了另外一个"函数"里面(这个时机是不知道的),所以我们自然要把当前正在执行的指令去压栈。这样,我们才能在异常处理程序执行完成之后,重新回到当前的指令继续往下执行

上下文切换

异常情况往往发生在程序正常执行的预期之外,比如中断、故障发生的时候。所以,除了本来程序压栈要做的事情之外,我们还需要把 CPU 内当前运行程序用到的所有寄存器,都放到栈里面。最典型的就是条件码寄存器里面的内容。

像陷阱这样的异常,涉及程序指令在用户态和内核态之间的切换。对应压栈的时候,对应的数据是压到内核栈里,而不是程序栈里。

像故障这样的异常,在异常处理程序执行完成之后。从栈里返回出来,继续执行的不是顺序的下一条指令,而是故障发生的当前指令。因为当前指令因为故障没有正常执行成功,必须重新去执行一次。

对于异常这样的处理流程,不像是顺序执行的指令间的函数调用关系。而是更像两个不同的独立进程之间在 CPU 层面的切换,所以这个过程我们称之为上下文切换

总结

当 CPU 遭遇了异常的时候,CPU 会通过“查表法”来解决这个问题。

在硬件层面和操作系统层面,各自定义了所有 CPU 可能会遇到的异常代码,并且通过这个异常代码,在异常表里面查询相应的异常处理程序。

在捕捉异常的时候, CPU 进行相应的操作,而在处理异常层面,则是由作为软件的异常处理程序进行相应的操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/454032.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】三种方式实现字符串(char*)/字符数组(char[ ])输入输出

前言 做题时经常需要用到字符串,写篇笔记加强记忆,本文用 4个例子实现字符串的输入输出操作。 scanf(); 从键盘输入数据时,遇到 “空格”、“回车” 都会终止。若要接受空格,使用 gets(); 代替 scanf(); 多个 scanf(); 同时出现…

TYPE C模拟耳机POP音产生缘由

关于耳机插拔的POP音问题,小白在之前的文章中讲述过关于3.5mm耳机的POP音产生原因。其实这类插拔问题的POP音不仅仅存在于3.5mm耳机,就连现在主流的Type C模拟耳机的插拔也存在此问题,今天小白就来讲一讲这类耳机产生POP音的缘由。 耳机左右…

瑞熙贝通实验室物联网管理平台新升级|支持远程开门视频监控与电源控制以及环境监测

瑞熙贝通实验室智能物联网管控平台:利用“互联网与物联网技术”有机融合,对实验室的用电安全监测、实验室环境异常监测(颗粒物监测、明火监测、可燃气体、烟雾监测、温湿度传感器、红外人体感应)、实验室人员安全准入、万物互联等…

全自动守护数据安全:全自动备份文件的重要性与高效方案

一、全自动备份文件:数据安全的坚实防线 在数字化时代,电脑成为我们生活和工作中不可或缺的重要工具。然而,随着电脑中存储的数据量不断增长,数据丢失或损坏的风险也随之上升。因此,全自动备份文件的重要性愈发凸显&a…

xcode15,个推推送SDK闪退问题处理办法

个推iOS推送SDK最新版本 优化了xcode15部分场景下崩溃问题,以及回执上传问题,近期您的应用有发版计划,建议更新SDK: 1)GTSDK更新到3.0.5.0以及以上版本; 2)GTCommonSDK更新到3.1.0.0及以上版本…

css实现高度是宽度一半的效果

1、方法一&#xff1a;使用变量:root、var()、clac()实现&#xff1a; 1.1 效果如下&#xff1a; 2.2 代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title>&l…

LM2903BIDR比较器芯片中文资料规格书PDF数据手册参数引脚图功能封装尺寸图

产品概述&#xff1a; M393B 和 LM2903B 器件是业界通用 LM393 和 LM2903 比较器系列的下一代版本。下一代 B 版本比较器具有更低的失调电压、更高的电源电压能力、更低的电源电流、更低的输入偏置电流和更低的传播延迟&#xff0c;并通过专用 ESD 钳位提高了 2kV ESD 性能和输…

hcia datacom课程学习(2):telnet与ssh

telnetssh所属层应用层应用层所应用的传输层协议tcptcp功能远程连接远程连接默认端口2322安全性很低较高功能组件分布客户端、服务器端客户端、服务器端linux环境不自带自带windows环境 win7有客户端和服务器端&#xff0c;但需要手动打开。 win10只有客户端&#xff0c;也需要…

<AI大模型学习>——《人工智能AI》

&#xff1c;AI大模型学习&#xff1e;——《人工智能AI》 一、AI大模型通识 1.AI介绍 人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;英文缩写为AI。 是新一轮科技革命和产业变革的重要驱动力量&#xff0c; 是研究、开发用于模拟、延伸和扩展人的智…

15双体系Java学习之数组的声明和创建

数组的声明 ★小贴士 可以使用int[] a;或者int a[];建议使用第一种风格&#xff0c;因为它将元素类型int[]&#xff08;整型数组&#xff09;与变量名清晰分开了。 在Java中声明数组时不能指定其长度。这种定义是非法的&#xff1a;int a[5]; 注意&#xff1a;上图显示的内存…

基于vue实现bilibili网页

学校要求的实验设计,基于vue实现bilibili网页版,可实现以下功能 (1)基本的悬浮动画和页面渲染 (2)可实现登录和未登录的页面变化 (3)在登录页面的,实现密码判断,或者短信验证方式的倒数功能 (4)实现轮播图 (5)实现预览视频(GIF) (6)页面下拉到一定高度出现top栏以及右下角的返回…

【计算机视觉】目标跟踪| 光流算法详细介绍|附代码

0、前言 在上篇文章中https://blog.csdn.net/Yaoyao2024/article/details/136625461?spm1001.2014.3001.5501&#xff0c;我们对目标跟踪任务和目标跟踪算法有了大致的了解。今天我们就来详细介绍一下其中的生成式算法的一种&#xff1a;光流法。 在介绍光流法之前&#xff…

学成在线_课程预览-视频播放测试_视频加载出错

问题 在进行课程预览界面的视频播放测试时界面提示视频加载出错。 如图所示JAVA特性讲解的第一小节视频加载出错。 查看课程计划会发现该小节已经进行了视频关联。 问题原因 此课程小节的关联视频在我们自己的minIO的桶中并不存在。所以前端从数据库中拿到的关联视频url是…

1960-2020年全球双边迁移数据库(Global Bilateral MigrationDatabase)

1960-2020年全球双边迁移数据库&#xff08;Global Bilateral MigrationDatabase&#xff09; 1、时间&#xff1a;1960-2000年&#xff0c;每10年一次具体为&#xff1a;1960年、1970年、1980年、1990年、2000年 2、来源&#xff1a;世界银行 3、指标&#xff1a;Country O…

零基础自学C语言|自定义类型:联合与枚举

✈联合体 &#x1f680;联合体的类型声明 像结构体一样&#xff0c;联合体也是由一个或者多个成员构成&#xff0c;这些成员可以不同的类型。 但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间。所以联合体也叫&#xff1a;共用体。 给…

node.js---EJS 模板引擎

什么是模板引擎 模板引擎是分离 用户界面和业务数据 得一种技术 什么事 EJS EJS 是一个高效的 JavaScript 得模板殷勤 EJS 初体验 下载&#xff1a; npm i ejs --save 引用 const ejs require(ejs) 配置 app.set("views",__dirname"/view");//设…

蓝桥杯刷题(二分)

前言&#xff1a; 最近学校的学业有点重&#xff0c;好多课的作业一下布置导致我时间紧张&#xff0c;今天好不容易找到了整块的时间来刷刷题&#xff0c;不过有几道题难度对我来说有一点大了&#xff0c;所以到现在为止也没做几道&#xff0c;希望自己在后面能更勤奋一点吧。 …

探索 MySQL 递归查询,优雅的给树结构分页!

一、概述 递归查询是一种在数据库中处理具有层级结构数据的技术。它通过在查询语句中嵌套引用自身&#xff0c;以实现对嵌套数据的查询。递归查询在处理树状结构、父子关系或层级关系的数据时非常有用。 在MySQL中&#xff0c;递归查询可以使用WITH RECURSIVE语句来实现。该语…

利用HubSpot出海CRM和人工智能技术提升出海业务的效率和效果

在当今数字化时代&#xff0c;智能化营销已经成为企业获取客户和扩大市场份额的关键策略。特别是对于出海业务而言&#xff0c;利用智能化营销技术来应对不同文化、语言和市场的挑战&#xff0c;已经成为企业竞争的关键优势。今天运营坛将带领大家探讨如何利用HubSpot CRM和人工…

隐式提交的引申之DB/SAP LUW

1、写在前面 之前发表过《聊聊更新表时的隐式提交》一文&#xff0c;向大家介绍隐式提交&#xff0c;对于数据库操作的作用。 有粉丝看过后&#xff0c;提出了自己的疑问&#xff1a; 首先解释一下&#xff0c;该粉丝大致的问题和代码含义为&#xff1a; 在创建销售订单增强…