CMU 15213笔记 第八章

Exception(CSAPP-8.1)

  • 在第三章中,我们已经知道程序执行中的两个控制流 —— 跳转和调用,但是这只是对于一个程序内部的控制,如果系统本身发生变化或者程序需要和系统交互,就需要新的控制方式

    • 系统交互举例:
      • 从硬盘读取数据
      • 用户按下Ctrl+c 终止程序
      • 产生除0错误
    • 新的方式——异常控制流
      • 用户代码通系统内核提供的接口将异常号传递给内核,内核通过内置的异常表决定采取的行动
        这里写图片描述
  • 异常分类

    • 异步异常(中断)
      • 计数器中断
        • 某一进程运行足够时间后,内核通过计数器中断拿回控制权
      • I/O中断
        • 从硬盘读取出数据后
        • 键入Ctrl+ C
        • 网路中的一个包接受完毕
    • 同步异常
      • Trap
        • 故意的异常
        • 返回到下一条指令
        • 作用:在用户程序和内核中提供接口
          • 当用户程序需要向内核请求服务时,例如读取文件,加载一个新的程序,转到内核程序
          • 用户模式的行为是被限制的,不可以访问一些内存和执行一些命令,所以要转移到内核模式
      • Fault
        • 可以恢复的错误
        • 返回到当前指令
        • 举例:缺页故障
          • 内存中没有需要的数据,需要从硬盘中读取
      • abort
        • 不可恢复的错误
          • 举例:
            • 非法指令
            • exit

Process(CSAPP-8.2)

  • 两个关键的抽象
    • 逻辑控制流
      • 通过上下文切换让每个程序好像单独占用处理器
      • 上下文切换保存的状态举例
        • 存放在内存中的程序代码和数据
        • 栈和寄存器
        • PC
        • 环境变量
          这里写图片描述

这里写图片描述

  • 私有地址空间
    • 通过虚拟内存让每个程序感觉在单独占用内存
      • 每个虚拟地址空间都有相同的通用结构
        这里写图片描述

进程控制(CSAPP-8.3,4)

  • fork
    • 创建一个子进程,除了返回的PID(进程ID)不同,其余全部相同
      • 两者互不影响,并发执行
      • fork返回两次,一次返回到父进程,一次返回到子进程
        • 父进程中返回子进程的PID(不为0)
        • 子进程返回0
          • 通过这个来判断父子进程
  • waitpid
    • 回收子进程
      • 当子进程结束时,保持终止状态知道父进程回收,此时子进程任然占据内存
        这里写图片描述
    • 第一个参数大于零,则等待ID为第一个参数的子进程结束
      • 若为-1,这等待任意进程结束
    • 如果没有子进程,则返回-1
  • execve
    • 在当前进程中加载一个新的程序,覆盖当前进程的地址空间,但没有创建一个新的进程
      这里写图片描述

Signal(CSAPP-8.5)

  • 当子进程完成后,会发送一个信号给父进程让他来回收自己
    • 内核对不同的信号有唯一的编码
    • 信号传递的整个过程分两个部分
      • 第一个部分为信号发送,由内核发送给进程
        • 当一个进程正在使用信号处理程序处理某一类型的型号时,同种信号不会被接受,直接被丢弃
        • 实际上第二个同种信号不会被丢弃,它被记录到pending组中,而之后的同种信号会被丢弃
          • 原因是pending组实际上是在接收到某一信号后,将对应的位设置为一,所以当存在pending时,我们只能确认有多的信号,而不能确认有几个
      • 上面说的pending是系统默认的一种信号block形式,当然我们可以显式block各种信号
      • 当进程处理完一个信号处理程序后,会查看pending组中待处理的信号,从最小的信号开始处理,知道没有待处理信号,然后会执行下一条程序
  • 安全的信号处理程序
    • 阻塞所有的信号
      • 处理程序和主程序共享全局变量
    • 用volatile声明全局变量
  • 竞争
    • 不能确定子进程和父进程谁先执行导致了竞争的出现
    • 难以稳定浮现错误
    • 具体见CSAPP第8.5.6节例子
    • -

非本地跳转(CSAPP-8.6)

  • 本地跳转指goto操作
    • 但是goto无法跳转到别的函数
    • 通过setjmp和longjmp可以直接从一个函数跳转到另一个函数,不用通过调用-返回操作
    • 但是这样可能会产生内存泄漏
  • setjmp记录当前的调用环境
  • longjump恢复调用函数
    • 这样可以从一个深层嵌套的函数中直接跳转到一个错误处理程序

这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/winter_wu_1998/article/details/80791325