在 Linux 中,进程的启动方式可以从“用户视角”和“内核视角”两个层面来理解。下面用通俗但系统的方式说明。
当你在终端执行一个命令时,其实是在 启动一个新进程。
ls
背后发生了什么?
fork() 创建一个子进程exec() 系列函数,把 ls 程序加载进来ls 进程开始运行✅ fork + exec 是 Linux 启动新进程的标准方式
sleep 100 &
& 表示后台运行#include <unistd.h>
int main() {
pid_t pid = fork();
if (pid == 0) {
// 子进程
execl("/bin/ls", "ls", NULL);
} else {
// 父进程
wait(NULL);
}
}
Linux 进程创建关系:
swapper(PID 0)
└── init / systemd(PID 1)
└── 各种用户进程
| 系统调用 | 作用 |
|---|---|
fork() |
复制当前进程,创建子进程 |
exec() |
用新程序替换当前进程 |
clone() |
创建线程/进程(更底层) |
wait() |
父进程等待子进程结束 |
init(或 systemd,PID 1)systemd 启动各种系统服务(都是进程)示例:
systemctl start nginx
| 启动方式 | 示例 |
|---|---|
| 命令行 | ls, vim |
| 后台运行 | command & |
| 程序调用 | fork + exec |
| 系统服务 | systemctl start xxx |
| 定时任务 | cron, at |
| 脚本执行 | bash test.sh |
ps -ef
或查看某个进程:
cat /proc/PID/cmdline
查看父进程:
ps -o pid,ppid,cmd
Linux 中,新进程几乎总是通过“已有进程调用 fork() 创建子进程,再调用 exec() 加载新程序”启动的。
如果你愿意,我也可以:
你想深入哪一块?