异常控制流

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