4. Process Control
进程空间的组件 Components
kernel 空间的组件大致如下:
- process address space map
- process 的当前 status
- process execution priority
- 当前 process 使用的 memory/cpu 的量
- 当前 process 打开的文件和 network port
- process signal mask (record of which signals are blocked)
- owner of the process
PID: process ID number
每个进程都有一个 kernel 赋予的 唯一 id
pid 是按照从小到大的顺序一一分配的
PPID: parent PID
unix 系统创建一个新的进程的时候并不是直接运行一个指定的 program, 而是分为两步
- 一个已有的进程必须 clone 自身来获得一个新的 process
- 新的进程执行新的 program
PPID 就是子进程指向父进程的
这个 ppid 大多是用来解决一些未识别的 进程的来源问题, 用来辅助 tracing
UID and EUID: real and effective user ID
UID 表示的是创造这个进程的用户, 或者说是对 parent 进程的 uid
的复制; 一般来说只有 owner/superuser 可以操作一个进程
EUID 指的是有效的 user ID, 也是一个 特殊的 UID
用来决定一个进程是否有权限来访问一个某些特定的资源和文件; 大多数时候的 uid 和
euid 是一致的, 但是可以通过 setuid 来进行设置更改
二者的同时存在是为了提供一个 identity 和 permission 的区分, 因为一个 setuid
程序可以临时改变一个 进程的权限 (也就是二者需要解除绑定)
saved UID: 在进程刚开始运行的时候保存一份 euid, 只要程序不要显示销毁这个 suid, 就可以随时用来切换回原始的权限状态
- 提权阶段: euid -> suid
- 降权阶段: suid -> uid, 最小化特权运行时间
GID and EGID: real and effective group ID
Control Terminal
对于大多数前台(非 daemon)进程来说, 都会有一个"控制终端"与之关联, 这个终端并不一定是真正的物理终端(如老式的串口机), 而是现代 Linux/UNIX 下常见的伪终端(pty)
控制终端会负责如下职能:
- 对相关进程的 stdin/ stdout/ stderr 绑定到哪个终端设备上
- 键盘信号的 分发: 比如 Ctrl-C 执行能终止程序之类的
而一般的 终端软件例如 kitty terminal 当你打开之后就会触发 一对 伪终端, master
(前端) 负责 供终端模拟器程序使用; slave(后端) 则被 shell 及其子进程当作真正的终端使用
进程的 lifecycle
在计算机的启动阶段, kernel 会自动创建并且下载许多 process, 例如 init 和
systemd 等指令, 这些进程会执行系统 startup 的脚本, 所有其他的
非内核创建的进程都是来自于这个进程
进程死亡的时候要预先通知 kernel 并且调用一个 _exit 指令来传递退出信号,
一般认为 0 是正常退出; 而在死亡进程完全消失之前还要通知其 parent , parent
进程也会通过一个 wait 指令来等待子进程的死亡, 同时也可以根据情况获得 child
进程的资源消耗情况
如果一个 parent 进程死得比子进程早, 那么孤儿 (orphan) 子进程会被 kernel 转移到 init 进程下, 这个时候
