首页 > 其他分享 >第八章 异常控制流

第八章 异常控制流

时间:2024-02-26 22:12:25浏览次数:26  
标签:执行 控制流 第八章 内核 信号 进程 上下文 异常

1. 异常

从给处理器加电开始,直到你断电为止

程序计数器假设一个值的序列(\(a_k\)是\(I_k\)的地址)

每次从\(a_k到a_{k+1}\)的过渡称为控制转移,这样的控制转移称为处理器的控制流

系统必须对系统状态的变化(\(I_k和I_{k+1}\)的地址不相邻)做出反应,这些变化不是一些必要的机制(比如跳转,调用,返回)
比如从网络传输的数据包需要到达网络适配器之后,需要将数据放到内存中
现代系统通过控制流发生突变来对这些情况做出反应。我们把这些突变称为异常控制流


处理器正在执行当前指令\(I_{curr}\)
处理器状态中发生一个重要的变化时,状态被编码为不同的位和信号。状态变化称为事件。

  • 事件可能和当前指令执行有关
    比如发生虚拟内存缺页,算术溢出,一条指令试图除以0
  • 也可能和当前指令执行无关
    比如一个I/O请求完成

在任何情况,处理器检测到有事情发生时,都会通过异常表进行跳转,到一个专门用来处理这类事件的操作系统子系统

异常处理

系统为每种异常分配了异常号。
当系统启动时,操作系统分配和初始化一张称为异常表的跳转表

异常表的起始地址放在一个叫做异常表基址寄存器的特殊cpu寄存器中

通过异常表的起始地址和异常号来转到相应的异常处理程序

异常的类别

异步同步的区别主要是异常产生的原因来自cpu内部还是外部

1. 中断

当敲一下键盘时,键盘控制器会向处理器的中断引脚发送信号,异常号放到系统总线上。这个异常号标识了引起中断的设备

2. 陷阱

陷阱是故意触发的异常。

当应用程序需要读取文件或者创建新的进程时,此时需要向内核请求服务,处理器提供了一个特殊的指令:syscall

执行syscall指令会导致一个到异常处理程序的陷阱,这个处理程序解析参数,并调用适当的内核程序。

3. 故障

故障由错误情况引起,可能能被故障处理程序修正。

一个经典实例是缺页异常
当指令引用一个虚拟地址,但该地址对应的物理页面不在内存中,此时需要从磁盘中取出。就会发生故障。
缺页处理程序将页面加载到内存,然后将控制返回给引起故障的指令。
指令再次执行时就没有故障的运行完成了。

4. 终止

终止是不可恢复的致命错误造成的结果,比如DRAM或者SRAM被损坏时发生的错误。

终止处理程序从不将控制返回给应用程序,只会终止这个应用程序

私有地址空间

进程为每个程序提供一种假象,好像它独占地使用系统地址空间

地址空间底部是保留给用户程序的。代码段总是从地址0x400000开始
地址空间顶部保留给内核

上下文

内核为每个进程维持一个上下文。上下文就是内核重新启动一个被抢占的进程所需的状态。
上下文由一些对象的值组成,比如通用目的寄存器,浮点寄存器,程序计数器,用户栈,状态寄存器,内核栈和各种内核数据结构(页表)

内核抢占当前进程并重新开始一个先前被抢占了的进程被叫做进程调度,由内核中的调度器处理。并使用一种上下文切换的机制来将控制转移给新的进程

上下文切换:

  • 保存当前进程的上下文
  • 恢复某个先前被抢占的进程被保存的上下文
  • 将控制转移给新进程

中断也可以引发上下文切换

进程A初始运行在用户模式中。当他执行系统调用read陷入到内核
磁盘读取数据需要较长的时间,所以内核执行从进程A到进程B的上下文切换。
当磁盘发出中断信号,表示数据已经从磁盘传送到内存,内核执行上下文切换从进程B到A

进程控制

1. 进程创建

父进程通过调用fork()函数创建进程

fork()执行一次返回两次
在父进程执行返回子进程的PID,在子进程执行返回0
因为所有进程的PID都是正数(非0),所以可以根据fork的返回值来判断是在哪个进程执行的。

我们还可以判断父进程和子进程哪个先执行,如下图

父进程和子进程会并发地执行fork()后的所有语句,且子进程在创建时会拷贝父进程的副本。


如下图,调用第一次fork()会创建一个子进程。
再调用第二次fork(),此时的两个进程会分别执行fork()
此时程序中有四个进程

2. execve函数

execve函数作用是调用加载器执行一个新的程序

第一个参数是执行的程序名字,第二个参数是参数列表,第三个参数是环境变量列表

对于下面这条指令

ls -lt /home/csapp

argv如下

信号

信号是一种更高层的软件形式的异常,允许进程和内核中断其他进程

比如,如果一个进程试图除以0,内核就会发送给该进程一个SIGFPE信号,这个信号对应的是浮点异常的事件

发送信号

1. 进程组:

每个进程都只属于一个进程组,进程组是由一个正整数进程组ID来标识的。

2. 用/bin/kill 发送信号

linux> /bin/kill -9 15213 //发送信号9给进程15213
linux> /bin/kill -9 -15213 //发送信号9给进程组15213的每个进程

3. 从键盘发送信号

对于

linux> ls|sort

会创建一个由两个进程组成的前台作业,这两个进程是通过Unix管道连接起来的
一个进程运行ls程序,一个进程运行sort程序

shell为每个作业创建一个独立的进程组,进程组id取自作业中父进程中的一个

4. 用kill函数发送信号

kill函数会根据pid的不同,做出不同的判断

5. 用alarm函数发送信号


alarm函数安排内核在secs秒后发送一个SIGALRM 信号给调用进程

标签:执行,控制流,第八章,内核,信号,进程,上下文,异常
From: https://www.cnblogs.com/algoshimo/p/18035701

相关文章

  • 《程序是怎样跑起来的》第八章——从源文件到可执行文件
    编译(Compilation):首先,程序员使用文本编辑器编写源代码,然后通过编译器将源代码转换为目标代码。编译器会进行词法分析、语法分析、优化和代码生成等步骤,最终生成可执行文件或库文件。链接(Linking):如果程序包含多个源文件或库文件,链接器会将这些文件中的目标代码连接在一起,形成最......
  • 《程序是怎样跑起来的》第八章
    上一章提到了源代码,源代码在任何情况下都能够编译和显示,但它并不能直接运行,因为CPU只能够解释和执行的代码叫做本机代码,所以使用源代码时都会转换成本机代码被CPU理解后运行。我们对EXE程序进行转储后,可以得知本机代码的本质就是数值序列其中的每个值都代表某个指令和数据。其中......
  • 《程序是怎样跑起来的》第八章读后感
    在阅读《程序是怎样跑起来的》这本书的第八章后,我对面向对象编程(OOP)这一重要的编程范式有了更深入的理解。作者通过清晰的解释和丰富的示例,让我领会到了OOP的核心思想:将复杂的程序分解为相对简单的对象,通过这些对象之间的交互来实现程序的功能。本章首先介绍了类和对象的概念,让我......
  • 第八章 从源文件到可执行文件
    第八章主要讲述了从源文件到可执行文件的转换过程,即程序的编译和链接。以下是该章节的总结:编译和链接的操作需要使用编译器何链接器来完成,所以本章重点讲述编译器和链接器的功能,介绍了程序从编写到运行的整个过程。计算机只能执行本机代码:源代码是不能直接运行的,因为CPU能直接解......
  • 《程序是怎样跑起来的》第八章读后感
    本章主题是从源文件到可执行文件。上章也有讲到源代码(sourcecode),源代码就是用编程语言编写的程序,也称为源程序,用源代码保存的文件叫源文件。在第七章中也有提到,CPU只能解释自身固有的机器语言,机器语言的程序叫本地代码,本地代码的内容其实就是各种数值的罗列,所以要将源代码转换为......
  • C#异常
    C#异常解决转载:https://www.cnblogs.com/txwtech/p/11836139.html右键项目--》属性--》生成--》高级--》语言版本选择你配置文件所对应的版本。或者:右键项目---》管理nuget程序包--》查找安装或者更新Microsoft.Net.Compilers......
  • 《程序是怎样跑起来的》第八章读书笔记
    用某种语言编写的程序就称为源代码,保存源代码的文件称为源文件。能把C语言等高级编程语言编写的源代码转换成本地代码的程序称为编译器。每个编写源代码的编程语言都需要其专用的编译器,将C语言编写的源代码转换成本地代码的编译器称为C编译器。编译器首先读入代码的内容,然后再把源......
  • 《程序是怎样跑起来的》第八章读后感
    从源文件到可执行文件的过程涉及到编译和链接两个主要步骤。这个过程大致如下:预处理:预处理器处理源代码中的预处理指令,例如#include、#define等。预处理后的文件通常被称为“预处理文件”或“PP文件”。编译:编译器(compiler)将预处理文件转换成目标文件(objectfile)。在这个过程中,......
  • 《程序是怎样跑起来的》第八章观后感
    我是计应232的学生张凯源,今天来分享《程序是怎样跑起来的》第八章观后感。这一章讲了源文件与可执行文件及其转换,用某种编程语言编写的程序就称为源代码,保存源代码的文件称为源文件,计算机只能运行本地代码,我们输入的源代码,计算机无法直接运行,需要运用编译器转换成本地代码才能运......
  • 《程序是怎样跑起来的》读后感——第八章 从源文件到可执行文件
    在读了本章后我受益颇深。因为CPU能,直接解析并运行的不是源代码,而是本地代码,所以计算机只能够直接运行本地代码。由书可知,用某种编程语言编写的程序称为源代码,保存源代码的文件称为源文件,用C语言编写的源文件的拓展名通常是“.c”。Windows中EXE文件的程序内容,使用的就是本地代码......