今天csapp学习了异常的相关概念。
程序内的执行流切换无非两种,一种是分支和跳转;另一种是调用和返回。但是为了响应某些的事件,例如键盘输入和ctrl+c终止程序;以及程序的缺页错误或者段错误,就需要另一种执行流切换的方式。这种特殊处理叫做异常。
异常是将事件交给内核处理的过程,实现的层级从低到高包含异常、进程切换、信号和非本地跳转。
首先异常的分类。异常事件按照是否出现于当前执行的程序内来区分同步异常和异步异常。同步异常是程序内的操作导致的,包括内陷、故障和错误。内陷是程序故意操作的,例如系统调用以及中断。而故障和错误则是无意的。故障出现后,内核可能恢复程序的故障状态,再次执行程序。但是错误出现了,程序会被终止。
另一个则是异常的处理过程。每一个异常都有一个异常号,内核的异常处理函数,会根据出现的异常号来做相应的操作。
进程是一种抽象,在运行的程序看来,自己拥有CPU和内存的使用权。进程切换的时候,需要保存当前程序的上下文,以便未来恢复程序的状态。这里介绍了几个函数:
- 获取进程信息:
getpid()
和getppid()
- 创建子进程:
fork()
- 终止进程:
exit()
- 在此进程上直接执行另一个进程
execve
这里也介绍了进程图,但是需要配合fork()
函数的行为来理解。
两个部分介绍完了,下一个异常就是信号了。信号是后台程序执行完毕后,内核给当前进程的一种通知。信号可以被进程忽略。进程收到信号后,有三种操作:
- 忽略
- 终止
- 交给信号处理函数处理信号
另一个异常就是非本地跳转。本地跳转就是程序在一个函数内的goto语句。非本地跳转实现了两个函数之间的跳转。这里讲了两个函数以及行为。
setjmp()
:执行后,会保存当前函数的状态longjmp()
:执行后,会恢复由setjmp
保存的状态,实现栈的切换。
还讲了伪并行-并发和真正的并行区别,就是同时运行的进程,如果只有一个CPU来处理,那就是并发;如果多个核心分别运行多个进程,则为并行。
标签:CSAPP,函数,程序,内核,跳转,进程,异常 From: https://www.cnblogs.com/shangshankandashu/p/18595953