20155311《信息安全系统设计基础》第14周学习总结
教材学习内容总结
第八章-异常控制
异常
进程
- 异常是允许操作系统提供进程的概念所需要的基本构造块。
进程:一个执行中的程序的实例。
- 上下文是由程序正确运行所需要的状态组成的,这个状态包括存放在存储器中的程序的代码和数据,它的栈、通用目的寄存器的内容、程序计数器、环境变量以及打开文件描述符的集合。
- 进程提供给应用程序的关键抽象:
- 一个独立的逻辑控制流,独占地使用处理器;
- 一个私有的地址空间,独占地使用存储器系统。
- 并发流:一个逻辑流的执行在时间上与另一个流重叠。
- 并发:多个流并发地执行的一般现象。
- 多任务:一个进程和其他进程轮流运行的概念。
- 时间片:一个进程执行它的控制流的一部分的每一时间段。
- 并行流:如果两个流并发的运行在不同的处理器核或者计算机上
用户模式和内核模式
- 模式位:用某个控制寄存器中的一个位模式,限制一个应用可以执行的指令以及它可以访问的地址空间范围。
- 设置了位模式,进程就运行在内核模式中,一个运行在内核模式中的进程可以中兴指令集中的任何指令,而且可以访问系统中任何存储器位置。
- 用户程序必须通过系统调用接口间接的当问内核代码和数据。
- 进程从用户模式变为内核模式的唯一方法是通过诸如中断、故障、或者陷入系统调用这样的异常。
- 上下文切换
- 上下文就是内核重新启动一个被抢占的进程所需的状态。
- 上下文切换机制: 保存当前进程的上下文, 恢复某个先前被抢占的进程被保存的上下文, 将控制传递给这个新恢复的进程。
- 引起上下文切换的情况
- 当内核代表用户执行系统调用时
中断时也可能引起上下文切换。如,定时器中断。
- 调度:内核可以决定抢占当前进程,并重新开始一个先前被抢占的进程。有内核中称为调度器的代码处理的。
进程控制
回收子进程
- 当父进程回收已终止的子进程时,内核将子进程的退出状态传递给父进程,然后抛弃已终止的进程。 一个终止了但还未被回收的进程称为僵死进程。
- 一个进程可以通过调用waitpid函数来等待它的子进程终止或者停止。
* #include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid,int *status,int options);//返回:若成功,返回子进程的PID;若WNOHANG,返回0;若其他错误,返回-1
- 修改默认行为,通过options设置: WNOHANG:默认行为是挂起调用进程。 WUNTRACED:默认行为是只返回已终止的子进程。 WNOHANG|WUNTRACED:立即返回,如果等待集合中没有任何子进程被停止或者已终止,那么返回值为0,或者返回值等于那个被停止或者已经终止的子进程的PID。
- 错误条件: 若调用进程没有子进程,那么waitpid返回-1,并且设置errno为ECHILD; 若waitpid函数被一个信号中断,那么返回-1,并设置errno为EINTR
信号
- 信号术语
- 发送信号的两个不同步骤:
- 发送信号:内核通过更新目的进程上下文中的某个状态,发送(递送)一个信号给目的进程。
- 接收信号:信号处理程序捕获信号的基本思想。
- 发送信号的两个原因: 内核监测到一个系统事件,比如被零除错误或者子进程终止。 一个进程调用了kill函数,显式地要求内核发送一个信号给目的进程。一个进程可以发送信号给它自己。
- 待处理信号:一个只发出而没有被接收的信号
- 一个进程可以有选择性地阻塞接收某种信号。 待处理信号不会被接收,直到进程取消对这种信号的阻塞。
一个待处理信号最多只能被接受一次,pending位向量:维护着待处理信号集合,blocked向量:维护着被阻塞的信号集合。
- 发送信号
- 进程组:每个进程都只属于一个进程组,进程组是由一个正整数进程组ID来标识的。getpgrp函数返回当前进程的进程组ID:默认地,一个子进程和它的父进程同属于一个进程组。 用/bin/kill/程序发送信号:一个为负的PID会导致信号被发送到进程组PID中的每个进程。 从键盘发送信号:作业:表示对一个命令行求值而创建的进程。外壳为每个作业创建一个独立的进程组。
- 用kill函数发送信号: 进程通过调用kill函数发送信号给其他的进程。父进程用kill函数发送SIGKILL信号给它的子进程。
- 用alarm函数发送信号:在任何情况下,对alarm的调用都将取消任何待处理的闹钟,并且返回任何待处理的闹钟在被发送前还剩下的秒数。 接收信号
- 当一个程序要捕获多个信号时,一些细微的问题就产生了。
- 待处理信号被阻塞。Unix信号处理程序通常会阻塞当前处理程序正在处理的类型的待处理信号。
- 待处理信号不会排队等待。任意类型至多只有一个待处理信号。因此,如果有两个类型为K的信号传送到一个目的进程,而由于目的进程当前正在执行信号K的处理程序,所以信号K时阻塞的,那么第二和信号就简单地被简单的丢弃,他不会排队等待。
- 系统调用可以被中断。像read、wait和accept这样的系统调用潜在地会阻塞进程一段较长的时间,称为慢速系统调用。在某些系统中,当处理程序捕获到一个信号时,被中断的慢速系统调用在信号处理程序返回时不再继续,而是立即返回给用户一个错误的条件,并将errno设置为EINTR。
- Signal包装函数设置的信号处理程序的信号处理语义:
- 只有这个处理程序当前正在处理的那种类型的信号被阻塞
- 和所有信号实现一样,信号不会排队等候
- 只要有可能,被中断的系统调用会自动重启。
- 一旦设置了信号处理程序,它就会一直保持,知道signal带着handler参数为SIG_IGN或者SIG_DFL被调用。
代码学习
- exec函数族
- fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相同的进程,在fork后的子进程中使用exec函数族,可以装入和运行其它程序(子进程替换原有进程,和父进程做不同的事),fork创建一个新的进程就产生了一个新的PID,exec启动一个新程序,替换原有的进程,因此这个新的被exec执行的进程的PID不会改变。
- exec函数族装入并运行程序path/file,并将参数arg0(arg1, arg2, argv[], envp[])传递给子程序,出错返回-1。
- 在exec函数族中,后缀l、v、p、e指定函数将具有某种操作能力
- exec1.c中execvp()会从PATH 环境变量所指的目录中查找符合参数file 的文件名,找到后便执行该文件,然后将第二个参数argv传给该欲执行的文件如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno中exevp函数调用成功没有返回,所以没有打印出“* * * ls is done. bye”这句话


