本课程探讨了在 Linux 系统中启动新进程的基本概念。理解这一机制有助于深入了解操作系统的内部工作原理。
Fork 和 Exec 模型
在 Linux 中创建进程的主要机制是现有进程使用 fork 系统调用克隆自身。fork 调用会创建一个几乎完全相同的子进程。这个新的子进程会获得自己唯一的进程 ID (PID),而原始进程则成为其父进程,由父进程 ID (PPID) 标识。
分叉后,子进程可以继续运行与父进程相同的程序,或者更常见的是,使用 execve 系统调用来加载和运行一个新程序。execve 调用有效地用新程序的内存空间替换了进程的内存空间,从而允许开始执行不同的任务。这种两步“fork-exec”模型是如何在 Linux 中创建进程的基石。
观察父子关系
我们可以使用 ps 命令来观察这种父子关系:
ps l
l 选项提供“长格式”视图,显示有关运行进程的更多详细信息。您会看到一个标记为 PPID 的列,代表父进程 ID。查看您当前 shell(例如 bash)的进程。当您运行 ps l 命令时,您会注意到您的 shell 进程的 PID 与 ps l 进程的 PPID 相匹配。这是因为您的 shell 分叉了自身以创建 ps 进程。
Init 进程
如果每个进程都是另一个进程的子进程,那么必然存在一个最初的祖先。这就是 init 进程。系统启动时,内核会创建 init 作为第一个用户空间进程,并为其分配 PID 1。init 进程是所有其他进程的最终父进程,并以 root 权限运行以管理系统。在系统关闭之前,它不能被终止,并且负责启动许多维持系统运行的服务。