### Kill 一个进程的时候都发生了那些事情，从父子进程角度讲

**1. 信号发送与接收**

当你执行 `kill <PID>` 时，操作系统内核会向指定的进程（通常是子进程）发送 `SIGTERM` 信号

- **如果目标进程是子进程**：父进程并没有直接参与这个过程。信号是由内核发送给目标进程的，由内核负责后续的调度和处理
- **如果目标进程是父进程**：同样，信号由内核直接发送。但父进程的死亡会对其子进程产生连锁反应

**2. 进程对信号的响应**

这是最关键的一步，也是 `SIGTERM` 和 `SIGKILL` 最大的区别所在

- **接收 `SIGTERM`（友好终止）**：
  - 这是一个“软性”的终止请求，目标进程可以**捕获（handle）**或**忽略（ignore）**这个信号
  - 如果目标进程有信号处理程序，它会执行相应的清理工作，例如：
    - 释放占用的内存、文件描述符等资源
    - 保存当前的工作状态
    - 优雅地关闭网络连接
  - 清理完成后，进程会正常退出
  - **父子进程关系**：如果被 `kill` 的是父进程，并且父进程捕获了 `SIGTERM` 并执行了清理，它可能会在退出前向它的子进程发送信号（例如 `SIGTERM`），或者等待子进程先退出。但如果父进程直接退出，其子进程会变成**孤儿进程**，被 `init` 进程收养
- **接收 `SIGKILL`（强制终止）**：
  - 这是一个“硬性”的终止请求，目标进程**无法捕获、忽略或阻止**这个信号
  - 操作系统内核会直接终止这个进程，**不会**给它任何机会执行清理工作
  - 这种方式非常粗暴，可能导致数据丢失、资源泄露（例如，没有关闭的文件、没有释放的锁），所以通常不建议作为首选
  - **父子进程关系**：
    - 如果被 `kill -9` 的是**子进程**，它会立即被内核终止。子进程会进入**僵尸状态**，其父进程需要调用 `wait()` 来收集它的退出状态，否则它会一直占用一个 PID
    - 如果被 `kill -9` 的是**父进程**，父进程会立即被内核强制终止。其所有子进程都会立刻变成**孤儿进程**，并被 `init` 进程（PID 1）收养。`init` 进程会负责等待它们终止，并清理它们的僵尸状态，避免系统资源泄露

**3. 进程状态转换与资源回收**

无论以何种方式终止，进程都会经历以下状态转换：

- **从运行状态到终止状态**：当一个进程终止后，它的所有资源（如内存页、文件描述符等）都会被释放
- **成为僵尸进程**：一个进程终止后，它的进程描述符（PCB）仍然保留在内存中，记录其退出状态，等待父进程来“收尸”。此时，该进程就进入了僵尸状态
- **父进程的责任**：为了避免子进程成为僵尸，父进程的责任是调用 `wait()` 或 `waitpid()`。一旦调用，内核就会将僵尸子进程的 PCB 彻底移除，释放其占用的 PID，完成最终的清理工作