当前位置:首页>Linux>Linux进程大赏:从“祖宗进程”到“打工进程”,看完秒懂进程的一生

Linux进程大赏:从“祖宗进程”到“打工进程”,看完秒懂进程的一生

  • 2026-10-11 02:28:08
Linux进程大赏:从“祖宗进程”到“打工进程”,看完秒懂进程的一生

用过Linux的小伙伴,大概率都敲过ps -ef 这个命令——屏幕上密密麻麻的一行行内容,就是Linux系统里正在“打工”的进程。

很多人对进程的理解,只停留在“程序运行的实例”这个干巴巴的定义上,一听到“父进程、子进程、0号进程、1号进程”就头大,更别说搞懂进程怎么“出生”、怎么“干活”、怎么“死亡”了。

今天就换个接地气的姿势,把Linux进程家族的“爱恨情仇”讲明白:把整个Linux系统比作一家“超级公司”,进程就是公司里的“员工”,从“祖宗级老板”到“底层打工仔”,每个进程都有自己的职责和归宿,风趣不枯燥,专业不打折!

一、先搞懂:进程到底是什么?

先给个绝对严谨的定义,记不住也没关系,后面类比会帮你吃透:进程是操作系统进行资源分配和调度的基本单位,是程序运行的实例。

简单说,程序是“死”的(比如你写的shell脚本、安装的nginx),而进程是“活”的——当你执行 ./test.sh 或者启动nginx时,操作系统就会给这个程序分配内存、CPU等资源,让它跑起来,这就变成了进程。

类比一下:程序就是“员工手册”,进程就是“照着手册干活的员工”——一本手册可以对应多个员工(一个程序可以启动多个进程,比如nginx多进程),每个员工都有自己的工作状态、专属资源。

二、Linux进程家族:谁是“祖宗”?谁是“大管家”?

Linux系统里的所有进程,都有一个共同的“祖宗”,往下代代衍生,形成一个“进程树”(就像公司的组织架构图)。其中最核心的几个角色,必须记牢。

1. 0号进程(idle/swapper):系统的“开山鼻祖”,隐形的幕后大佬

0号进程是Linux系统启动时,第一个被创建的进程,没有“爹”(父进程),是所有进程的“老祖宗”。

它的职责特别“底层”,不直接干“业务活”,主要负责进程调度——当系统没有其他任务可运行时,0号进程就会出来“idle”(空闲等待)。在Linux内核中,它也被称为 swapper 进程,负责一些初始化工作。

类比一下:0号进程就像公司的“奠基创始人”,搭建完基础设施后就退居幕后,不参与日常管理,只在没有员工干活的时候出来转转。

重点提醒:0号进程是内核态进程,由内核直接创建。在常规使用 ps 命令时确实看不到它,因为它不体现在用户态的进程列表里,但它一直默默在后台支撑着整个系统。

2. 1号进程(init/systemd):系统的“大管家”,所有孤儿进程的“直接爹”

0号进程启动后,做的第一件事,就是创建1号进程——这是Linux系统中第一个用户态进程,也叫“初始化进程”。

早期的Linux系统,1号进程是init(相当于“老管家”),现在大部分主流发行版(如CentOS 7+、Ubuntu 15.04+),1号进程已经变成了 systemd(相当于“智能大管家”),功能更强大。

它的核心职责是:收养所有“孤儿进程”、启动和管理系统服务。

类比一下:1号进程就像公司的“CEO”,由“创始人”(0号进程)任命,负责管理整个公司的日常运营——启动所有必要的“部门”(系统服务),如果某个“部门经理”(父进程)离职(退出),留下的“员工”(子进程)就由CEO直接接管,不会变成“无主孤儿”。

严谨补充:1号进程的PID(进程ID)永远是1,这是固定的!不管你重启多少次系统,只要系统正常启动,1号进程就会存在,直到系统关机。

3. 父进程与子进程:职场里的“上下级”,一脉相承

除了0号和1号进程,系统里绝大多数进程,都是“父子关系”——一个进程(父进程)通过 fork() 系统调用,创建出另一个进程(子进程),就像“上级”培养“下级”。

举个生活化的例子:你在终端里敲 ls 命令,终端进程(父进程)就会创建一个 ls 进程(子进程),ls进程干完活(列出目录内容)后,就会“离职”(退出),控制权再交回终端进程。

严谨知识点(必记):

  • 父进程创建子进程时,会复制自己的资源给子进程,子进程拥有独立的PID,和父进程互不干扰。

  • 子进程的“爹”(父进程PID,简称PPID),就是创建它的进程的PID;父进程可以通过 wait() 或 waitpid() 等待子进程退出,回收子进程的资源(避免资源泄漏)。

  • 如果父进程先于子进程退出,子进程就会变成“孤儿进程”,此时1号进程(systemd/init)会自动收养它,成为它的新父进程。

三、进程的“一生”:从“出生”到“死亡”,每一步都有规矩

和人一样,Linux进程也有“生老病死”,从创建(出生)、运行(干活),到退出(死亡)、资源回收(销毁),每一步都有明确的规则。

1. 进程的“出生”:只有一种方式——fork()

Linux里,所有用户态进程的“出生”,都离不开 fork() 系统调用(除了0号和1号进程)。

简单说:父进程执行 fork() 后,系统会复制父进程的所有资源,创建一个新的子进程。此时会有两个“一模一样”的进程在运行——唯一的区别是:父进程的 fork() 返回值是子进程的PID,子进程的 fork() 返回值是0。

类比一下:就像公司里的“老员工”(父进程),复制自己的“工作经验”(资源),培养出一个“新员工”(子进程)。新员工和老员工的“工作内容”(代码)一样,但有自己的“工号”(PID)。

补充:子进程创建后,常常会用 exec() 系统调用,替换自己的代码段,执行新的任务(比如父进程是终端,子进程通过 exec() 执行 ls 命令)。fork() 和 exec() 的组合,是Linux启动新程序的经典方式。

2. 进程的“干活”:抢占CPU,各凭本事

进程创建后,就进入“运行状态”,但Linux系统里的进程有很多,CPU资源有限,所以不是所有进程都能“一直干活”,而是由内核的“进程调度器”分配CPU时间片,轮流干活。

这里有个核心概念:进程优先级。

Linux中,进程的优先级用 nice 值来表示,范围是 -20 到 19,共40个级别。nice 值越小,优先级越高(-20是最高优先级,19是最低优先级)。

默认情况下,进程的 nice 值是 0。

操作命令:

  • 用 top 或 ps -l 命令可以查看进程的 nice 值(NI列)。

  • 启动新进程时设置优先级:nice -n 5 ./test.sh(将新进程的nice值设为5,优先级较低)。

  • 调整已运行进程的优先级:renice -n 10 -p 1234(将PID为1234的进程nice值改为10)。

3. 进程的“死亡”:两种结局

进程不会一直“活”着,当它完成任务,或者出现错误,就会“死亡”。

(1)正常退出:功成身退,体面离场

就像员工“正常离职”,完成了自己的工作,主动提交离职申请。

常见的正常退出方式:

  • 进程执行完所有代码,自然退出(比如 ls 命令列出目录后,自动退出)。

  • 进程调用 exit() 函数,主动退出。

  • 进程从 main 函数返回。

严谨点:正常退出的进程,会返回一个“退出状态码”(0表示成功,非0表示失败)。父进程可以通过 wait() 获取这个状态码。我们执行 echo $? 命令,就能查看上一个进程的退出状态码,若返回0,说明进程正常退出。

(2)异常退出:意外翻车,被迫离场

就像员工“被开除”,或者“意外离职”,不是主动退出。

常见的异常退出方式:

  • 收到信号:比如我们敲 Ctrl+C,就是给进程发送 SIGINT 信号,强制终止进程。

  • 进程崩溃:比如段错误(Segmentation Fault)、非法访问内存,内核会直接终止进程。

  • 使用 kill -9 PID 强制结束进程(发送 SIGKILL 信号)。

4. 进程的“僵尸化”与“销毁”:一个必知的坑

很多人以为,进程“死亡”后就结束了——其实不是!进程死亡后,会变成“僵尸进程”(Zombie Process),需要父进程“善后”(回收资源)。

为什么会有僵尸进程?

当子进程结束运行时,它会向父进程发送 SIGCHLD 信号,并保留自己的进程控制块(PCB),等待父进程来读取它的退出状态。如果父进程没有调用 wait() 或 waitpid(),子进程的PCB就会一直驻留在内存中——这就是僵尸进程。

僵尸进程的危害:

  • 僵尸进程不会占用CPU,但会占用PID资源和少量内存(保留PCB信息)。

  • 如果大量产生僵尸进程,会导致系统PID资源耗尽,无法创建新进程。

类比一下:员工离职后,需要办理“离职手续”(资源回收),比如交还工牌、电脑。如果人事部门(父进程)一直不办手续,这个员工的档案(PCB)就会一直占用公司资源。

如何解决僵尸进程?

  • 让父进程调用 wait() 或 waitpid() 回收资源。

  • 或者终止父进程(此时僵尸进程会被1号进程收养,1号进程会自动回收它的资源)。

5. 孤儿进程:不幸中的万幸

与僵尸进程相对的是“孤儿进程”:如果父进程先于子进程退出,子进程就变成了孤儿进程。

孤儿进程怎么办?

内核会将孤儿进程的父进程设置为1号进程(init/systemd),由1号进程负责回收。所以孤儿进程不会造成资源泄漏,是安全的。

四、进程的几种状态(看懂top命令必备)

在 top 或 ps 命令中,进程的状态用字母表示:

状态

字母

说明

类比

运行

R

正在运行或正在运行队列中等待

员工正在工位干活

睡眠

S

可中断睡眠,等待某事件完成

员工在茶水间等咖啡

深度睡眠

D

不可中断睡眠,通常等待IO

员工在开会,谁叫都不理

停止

T

暂停运行,通常收到SIGSTOP信号

员工被暂停工作

僵尸

Z

已退出但未被父进程回收

离职但没办完手续的员工

五、必记重点:一张表理清核心知识点

知识点

核心说明

生活化类比

0号进程

内核态,系统第一个进程,负责调度和初始化,PID=0,常规ps看不到

公司奠基创始人,退居幕后

1号进程

用户态第一个进程,PID=1,收养孤儿进程,管理系统服务(init/systemd)

公司CEO,管理日常运营

父进程

通过fork()创建子进程,可通过wait()回收子进程资源

部门经理,培养新员工

子进程

由父进程创建,有独立PID,父进程退出后成为孤儿进程

新员工,跟着经理干活

fork()

创建子进程,复制父进程资源,返回两次(0给子,PID给父)

老员工复制自己带新人

exec()

替换当前进程的代码段,执行新程序

员工转岗,换工作内容

正常退出

执行完代码或调用exit(),返回状态码

员工正常离职

异常退出

收到信号或崩溃,非自愿终止

员工被开除或意外离职

僵尸进程

进程死亡,父进程未回收资源,状态为Z,占用PID

离职未办手续,占工位

孤儿进程

父进程先退出,子进程被1号进程收养

经理离职,员工被CEO接管

nice值

优先级参数,-20~19,越小优先级越高

员工职级,数字越小越核心

六、最后总结:记住3句话,吃透Linux进程

1.  Linux进程树:0号生1号,1号生万物,所有进程都有“爹”(除了0号),孤儿进程归1号管。

2.  进程的一生:fork() 出生 → 调度干活(nice值影响优先级) → exit()/信号死亡 → 父进程回收(没回收就是僵尸)。

3.  核心区分:僵尸进程占PID不占CPU,必须回收;孤儿进程被1号收养,安全无危害。

其实Linux进程没有那么难,只要把“进程家族”的关系和“一生的流程”搞懂,再结合命令实操(ps、top、kill、nice),很快就能上手。

如果觉得这篇文章帮你理清了思路,不妨转发给身边学Linux的朋友,帮他们避开“进程误区”❤️

最新文章

随机文章