异常
异常是异常控制流的一种形式,它一部分由硬件实现,一部分由操作系统实现。
异常就是控制流中的突变,用来响应处理器状态中的某些变化。
处理器发现异常时会进行一个间接过程调用,到一个操作系统子程序,即异常处理程序。
异常处理程序完成处理后会依据异常类型,产生以下三种情况:
- 将控制返回当前指令,即正在执行的指令。
- 返回给下一条指令。
- 终止被中断的程序。
异常处理
异常号:系统为每种类型的异常分配的唯一的非负整数。
异常表:系统启动时操作系统就会初始化一张条转变,使得条目k包含异常k的处理程序的地址。
关系:
异常号是到异常表中的索引,异常表的起始地址放在异常表基址寄存器。
异常的类别
1.中断
- 异步发生
- 来自处理器外部的I/O设备的信号的结果
- 返回下一条指令
2.陷阱
- 陷阱是有意的异常
- 是执行一条指令的结果
- 最重要的用途——系统调用
3.故障
- 由错误状况引起,可能能够被故障处理程序修正
- 结果要么重新执行指令(就是返回当前指令地址),要么终止
- 典型示例:缺页异常
4.终止
- 是不可恢复的致命错误造成的结果
- 通常是一些硬件错误
进程
异常是允许操作系统提供进程的概念所需要的基本构造块。
进程的一个经典定义就是一个执行中的程序的实例。
进程提供给应用程序的关键抽象:
- 一个独立的逻辑控制流:独占的使用处理器
-
一个私有的地址空间:独占的使用存储器系统
逻辑控制流
一系列的程序计数器pc的值,分别唯一的对应于包含在程序的可执行目标文件中的指令,或者是包含在运行时动态链接到程序的共享对象中的指令,这个PC值的序列就叫做逻辑控制流。
进程是轮流使用处理器的。每个进程执行它的流的一部分,然后被抢占,然后轮到其他进程。但是进程可以向每个程序提供一种假象,好像它在独占的使用处理器。
并发流
一个逻辑流的执行在时间上与另一个流重叠,称为并发流。
多个流并发地执行的一般现象称为并发。
- 并发:多个流并发的执行
- 多任务:一个进程和其他进程轮流运行(也叫时间分片)
- 时间片:一个进程执行它的控制流的一部分的每一时间段
如果两个流并发地运行在不同的处理器核或者计算机上,我们称它们为并行流,它们并行的运行,且并行的执行。
进程控制
获取进程ID
getpid函数
每个进程都有一个唯一的正数进程ID(PID)。
getpid返回调用进程的PID。
getppid返回它的父进程的PID。
创建和终止进程
exit函数
进程总是处于以下三种状态:
- 运行。
- 停止。
- 终止:1.收到终止进程的信号;2.从主程序返回;3.调用exit函数。
创建进程
fork函数
- 调用一次,返回两次:父进程返回子进程的PID,子进程返回0.如果失败返回-1。
- 并发执行。
- 相同的但是独立的地址空间。
- 共享文件:相同:用户栈、本地变量值、堆、全局变量值、代码 不同:私有地址空间
回收子进程
waitpid函数
进程终止后还要被父进程回收,否则处于僵死状态。
如果父进程没有来得及回收,内核会安排init进程来回收他们。init进程的PID为1。
一个进程可以通过调用waitpid函数来等待它的子进程终止或停止。
成功返回子进程PID,如果WNOHANG,返回0,其他错误返回-1。
错误条件:
- 如果调用进程没有子进程,那么waitpid返回-1,并且设置errno为ECHILD。
- 如果waitpid被一个信号中断,那么他返回-1,并且设置errno为EINTR。
wait函数:waitpid的简单版本。成功返回子进程的PID,出错返回-1。
让程序休眠
sleep函数
sleep函数使一个进程挂起一段指定的时间。
返回值是剩下还要休眠的秒数,如果到了返回0。
pause函数
让调用函数休眠,直到该进程收到一个信号。
加载并运行程序
execve函数
execve函数加载并运行可执行目标文件filename,且带参数列表argv和环境变量列表envp。
只有当出现错误时,例如找不到filename,execve才会返回到调用程序。
execve一次调用从不返回。