进程是什么?

进程 (process) 是 OS 对于正在运行的程序实例的抽象。
进程的组成,in terms of machine state

  • 进程可以访问的记忆体,即其地址空间 (address space)
  • 一系列寄存器 (registers),包括程序计数器 PC,栈指针 SP,帧指针 FP 等
  • 与进程访问的存储设备有关的 I/O 信息

进程状态

进程执行的生命周期 (life cycle) 中经历的一系列离散状态。

  • 新建 (new)
  • 就绪 (ready)
  • 运行 (run)
  • 中止 (terminate):若中止但 PCB 未被 OS 回收,僵尸进程 (zombie process)
  • 阻塞 (block):进程自身触发,通常是在等待某个事件发生(如 I/O 完成)或资源可用
  • 挂起 (suspend):外部触发,通常是被 OS 或用户暂停

数据结构

OS 用于管理进程的数据结构。

进程控制块 (Process Control Block, PCB) 存储某个进程的所有信息,包括状态,寄存器上下文 (register context),调度信息,统计信息,信号处理器等。

OS 的进程表 (process table),维护了当前所有进程的 PID 和 PCD 的映射。就绪列表 (ready list) 与阻塞列表 (blocked list)。

进程 API

  • fork()父进程 (parent process) 通过复制自身创建子进程 (child process)。若在父进程内,返回子进程 PID;若在子进程内,返回 0。
  • exec() 族:改头换面,用新程序替换当前进程的内存空间。
  • wait() 族:父进程阻塞自身,等待子进程终止。子进程终止后成为僵尸进程,父进程获取相关信息 e.g., wait(&status) 后 OS 将其回收。

fork()exec() 的工作方式并不很符合直觉:但它们的实现足够简单,组合的表达能力足够强大。一些经典的 features 如输入输出重定向 (input/output redirection) 与管道 (pipe) 都建立在 fork()exec() 的二分上。

Lampson's Law

把事情搞对 (Get it right. Neither abstraction nor simplicity is a substitute for getting it right)

信号

信号 (signal) 用于通知进程某个事件的发生。

信号的发出。

  • 同步信号 (synchronous signal):由进程自身在执行指令时触发,通常表示程序 bug 或异常条件。如 非法地址访问 SIGSEGV,除零错误 SIGFPE 等。
  • 异步信号 (asynchronous signal):由外部事件触发,通常表示外部控制或通信。如用户 Ctrl-C 退出 SIGINT,子进程终止 SIGCHLD 等。

信号的处理。

  • 捕获 (catch):使用 OS 默认或自定义的信号处理函数 (signal handler)
  • 忽略 (ignore):通知 OS 该信号不会被处理
  • 屏蔽 (mask):通知 OS 不要发送某类型的信号

SIGKILL 与 SIGSTOP 不会被捕获,忽略或屏蔽;他们将强制杀死或暂停进程。

用户

用户 (user) 或超级用户 (superuser: UNIX root, Windows admin)。普通用户仅能控制自己创建的进程。

阅读