异常控制流
- 异常控制流
- 层次
- 低层次:异常。
- 高层次:进程上下文切换、信号、非局部跳转。
- 异常分类
- 异步:由外部事件引起。
- 中断。
- 信号。
- 同步:由指令执行结果导致。
- 陷阱:如系统调用、断点、特殊指令等。
- 故障:如缺页、保护异常。
- 故障:如非法指令。
- 异步:由外部事件引起。
- 层次
- 进程控制
- 概念
- 参考进程。
- 常用系统调用
pid_t getpid():获取当前进程 PID。pid_t getppid():获取父进程 PID。pid_t fork():复制当前进程,在父进程和子进程中返回,父进程返回子进程 PID,子进程返回0。错误返回-1。调用一次,返回两次。void exit(int status):退出进程,状态为status。调用一次,从不返回。int wait(int *child_status):等待任意一个子进程终止,返回子进程的返回值,在child_status中填充详细状态信息。pid_t waitpid(pid_t pid, int *status, int options):等待特定 PID 的子进程终止。int execve(char *filename, char *argv[], char *envp[]):运行位于filename的程序,替换当前进程上下文为目标进程。调用一次,正常运行则不返回。
- 进程图
- 概念
- 信号
- 常见信号
SIGINT:中断程序运行,在 shell 中由^C触发,默认终止程序运行。SIGKILL:强制终止程序运行,不可以被覆盖或忽略。SIGSEGV:段错误触发,默认终止程序运行。SIGALRM:时钟信号触发,默认终止程序运行。SIGCHLD:子进程暂停或终止时触发,默认忽略。
- 发送和处理
- 发送方式:
- 当进程出现特定行为后或对此进程使用
kill()系统调用,内核发送对应信号给进程。 - 内核通过更新目标进程的上下文状态来实现发送信号。
- 当进程出现特定行为后或对此进程使用
- 信号的屏蔽:
- 通过
sigprocmask()可以屏蔽部分信号的接收。 SIGKILL、SIGSTOP等不可以被屏蔽。- 进程正在处理某个信号时,此信号被隐式屏蔽。
- 通过
- 信号的接收:
- 信号发送给进程组的 leader 时,信号发送给进程组里的所有进程。
- 进程上下文中保存一个位向量,每个位对应一个信号。
- 向进程发送信号同时,目标进程的位向量的对应位被设置为
1。 - 进程接收信号后,位向量的对应位被设置为
0。 - 只有在调度到进程后,才可以开始接收进程的信号,如果没有需要处理的信号,则执行正常代码。
- 已有一种信号处于已发送但是未接收时,再发送同类信号直接丢弃。
- 发送方式:
- 信号处理程序
- 进程可以通过
handler_t *signal(int signum, handler_t *handler)设置自定义信号处理程序。 SIG_IGN为忽略信号,SIG_DFL为对应信号的默认处理程序。其他情况为自定义函数的指针。
- 进程可以通过
- 常见信号

