# 进程管理

## 进程管理

关于进程，需要记住三个组成部分：

* `程序文件（Program file）` - 代码和数据
* `进程映像（Process image）` - 存储栈、当前定义的变量、数据、地址空间等[更多信息](https://tldp.org/LDP/LG/issue23/flower/psimage.html)；当需要运行时，操作系统知道如何使用这个映像重新创建进程
* `进程（Process）` - 内存中运行的程序

当进程开始运行时，它会从父进程继承`用户ID（user-id）`和`组ID（group-id）`。这个信息控制进程的访问级别。你可以使用[setuid](/linux-an-quan/overview/file.md#setuid-bit)或[setgid](/linux-an-quan/overview/file.md#setgid-bit)来启用进程继承文件所有者权限。

### 进程属性

![](https://drawings.jvns.ca/drawings/process.png)

每个进程都有以下属性：

* 唯一标识符，称为进程ID或`pid`
* 指向生成它的父进程的链接

有一个特殊的根父进程称为`init`，它通常有`pid` 1。`init`的`ppid`是0（传统上意味着它没有父进程）。`pid` 0对应内核调度器，它不是用户进程。

> `systemd`现在正在Linux上取代`init`，它解决了`init`的一些问题并且整体更稳定，更多内容请参见[这里](https://www.tecmint.com/systemd-replaces-init-in-linux/)

### 进程生命周期

UNIX中进程工作有一个通用模式：

1. 通过克隆现有父进程创建新的子进程 [fork()](https://man7.org/linux/man-pages/man2/fork.2.html)
2. 这个新的子进程调用[exec()](https://man7.org/linux/man-pages/man3/exec.3.html)来替换子进程中运行的父进程，用子进程想要运行的进程
3. 子进程调用[exit()](https://man7.org/linux/man-pages/man3/exit.3.html)来终止自己；它只传递退出码；`0`表示成功，其他都是错误码
4. 父进程需要调用[wait()](https://man7.org/linux/man-pages/man2/waitid.2.html)系统调用来获取这个退出码

这个周期为每个生成的进程重复。

![](/files/MIpemak4KeTGMikmuy8t)

这里有一些可能出错的情况：

* 如果父进程不调用`wait()`怎么办？这会导致`僵尸进程`（zombie process）- 这是一个资源泄漏，因为操作系统在退出码被父进程消费之前无法清理进程
* 如果父进程在子进程之前死亡怎么办？这会导致`孤儿进程`（orphan process）；`孤儿进程`被`init`进程（特殊的根父进程）收养，然后等待子进程完成

父进程如何从子进程获取额外信息？使用退出码是不可能的。但是，有其他方法可以进行[进程间通信](/linux-an-quan/overview/inter-process-communication.md)。

### 进程状态

进程可以处于以下几种状态：

* **运行（Running）**: 正在CPU上执行
* **就绪（Ready）**: 等待CPU执行
* **阻塞（Blocked）**: 等待某个事件（如I/O操作）
* **僵尸（Zombie）**: 已终止但父进程尚未调用`wait()`
* **孤儿（Orphan）**: 父进程已终止，被`init`进程收养

### 进程管理命令

```bash
# 查看当前进程
$ ps
$ ps aux      # 详细信息
$ ps -ef      # 完整格式

# 查看进程树
$ pstree

# 动态查看进程
$ top
$ htop        # 更友好的界面

# 终止进程
$ kill <pid>          # 正常终止
$ kill -9 <pid>       # 强制终止
$ killall <name>      # 按名称终止

# 后台运行进程
$ command &
$ nohup command &     # 忽略挂断信号

# 查看进程详细信息
$ /proc/<pid>/status
$ /proc/<pid>/cmdline
```

### 进程优先级

```bash
# 查看进程优先级
$ top

# 更改进程优先级
$ renice -n 10 -p <pid>    # 降低优先级
$ renice -n -5 -p <pid>    # 提高优先级

# 以特定优先级启动进程
$ nice -n 10 command        # 低优先级
$ nice -n -5 command       # 高优先级
```

## 参考资料

* [How Unix Works: Become a Better Software Engineer](https://neilkakkar.com/unix.html) - 深入了解UNIX工作原理
* [Linux Process Management](https://linuxconfig.org/linux-process-management) - Linux进程管理指南
* [Understanding Linux Processes](https://www.baeldung.com/linux/understanding-processes) - 理解Linux进程


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gitbook.cdxiaodong.life/linux-an-quan/overview/process.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
