进程定义:进程是操作系统中的一次执行过程,它是操作系统进行资源分配和调度的基本单位;

进程(静态代码)-> 加载到内存 -> 分配资源  进程是程序的 “动态执行过程”

只要用户执行了一个程序,在内核空间就会创建一个task_struct结构体,这个结构体就代表当前的进程,进程运行产生的所有的信息(如进程状态、PID、内存指针等)都被放到这个结构体中保存着;

进程执行完之后,task_struct会被内核回收;如果异常崩溃,内核也会清理资源(避免僵尸进程);

结构体放在内核空间

进程的核心特征

•动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的;

•并发性:任何进程都可以同其他进程一起并发执行;

•独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;

•异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程各自独立、不可预知的速度向前推进;

程序与进程的区别

对比维度 程序 (Program) 进程 (Process)
定义 是静态的指令集合,存储在磁盘上的可执行文件(如 .exe 等);未执行时不占用系统资源。 是程序的动态执行过程,是程序运行时的实例,占用 CPU、内存、I/O 等系统资源,有生命周期。
存在形式 静态存在,以文件形式长期存储。 动态存在,随程序启动而创建,随执行结束而销毁。
资源占用 不占用 CPU、内存等运行时资源,仅占用磁盘存储空间。 占用 CPU、内存、文件句柄、网络端口等系统资源,有独立的地址空间。
状态 无状态(仅为指令和数据的静态集合)。 有状态(如运行态、停止态等),状态会随系统调度变化。
独立性 多个程序之间相互独立,无直接关联(除非通过文件等外部方式交互)。 每个进程有独立的地址空间和资源,进程间默认不共享数据(需通过进程间通信机制实现)。
示例 如硬盘上的“浏览器.exe”文件。 双击“浏览器.exe”后运行的浏览器窗口。

程序与进程的关联

•进程是程序的执行过程,一个程序可以对应多个进程(如同时打开多个浏览器窗口);

•程序是进程的“模板”,进程是程序的“运行态体现”;

•进程的执行过程本质是按程序指令逐步推进,程序的逻辑决定进程的行为;

•同一程序的多个进程共享程序的代码段(只读),到各自拥有数据段(独立);

•关闭进程后,程序文件仍存在于磁盘;删除程序文件后,已运行的进程可继续执行(直到依赖文件时出错);

进程的组成

进程是由三个部分组成的,分别为进程控制块(PCB)、文本段、数据段;

•进程控制块(PCB,Process Control Block):PCB是操作系统用于管理和控制进程的核心数据结构,每个进程在内存中都有唯一的PCB,它记录着进程的所有关键信息(如进程识别信息、进程状态信息、内存管理信息、资源占用信息等),是操作系统感知进程存在的依据;

•文本段:是进程中存储可执行指令的内存区域,即程序编译后生成的机器码;为了防止程序意外修改自身指令,文本段通常被设置为只读;如果多个进程运行同一个程序,他们可以共享同一份文本段,节省内存空间;编译后的指令数量是固定的,文本段的大小在进程运行期间不会改变;

•数据段:是用于存储进程运行过程中需要的数据;根据数据“初始化状态”和“可修改性”,分为初始化数据段、未初始化数据段、堆、栈;

虚拟地址与物理地址的映射关系

Linux系统进程类型

Linux系统下有三种进程类型,分别是交互进程、批处理进程和守护进程;

•交互进程:

•定义:由shell维护,需要用户在终端手动启动的进程,通过shell和用户进行交互(用户交互输入/输出);

•特点:依赖终端环境,通常在前台运行,生命周期与用户操作相关;

•批处理进程:

•定义:无需用户实时交互,优先级比较低,按预设任务序列自动运行的进程,通常在后台执行;

•特点:优先级较低(避免占用关键资源),多通过脚本或任务调度工具启动;

•守护进程:

•定义:系统启动时自动运行的后台进程,独立于终端,通常随系统启动而启动,随系统关闭而终止,用于提供持续服务;

•特点:运行时脱离终端;

进程的状态

在Linux系统中,进程会因资源占用、执行阶段不同,呈现多种状态;

•运行状态(R):也称之为可运行状态,就是处于运行状态的进程,正在CPU执行或等待CPU调度;

•可中断睡眠状态(S):进程在等待某个事件(如等待I/O操作、等待特定信号等)完成,可被信号唤醒;

•不可以中断睡眠状态(D):进程正在等待关键硬件操作完成,不能被信号中断,确保数据完整性;

•停止状态(T):进程被暂停执行,通常是收到了特定的信号(如SIGSTOP(暂停进程))或者在调试程序时被调试器暂停,可被信号恢复执行(如SIGCONT);

•僵尸状态(Z):进程已终止,但资源未被回收,等待父进程进行回收;

•死亡态(X):进程彻底终止,资源全部释放,是一个瞬间状态,几乎无法观测到;

进程的附加状态

在Linux系统中,进程除了基础状态之后,还会有一些附加状态标记,用于补充说明进程的特殊属性;

•+(前台进程组):表示进程属于前台进程组,与当前终端直接关联,用户可以通过终端输入直接控制;

•l (多线程进程):表示进程包含线程(LWP),通常对应多线程程序;

•N(低优先级进程):表示进程的nice值为正数(NI > 0),优先级较低,CPU资源优先给其他进程;

•<(高优先级进程):表示进程的nice值为负数(NI < 0),优先级较高,会优先获取CPU资源;

•s(会话leader进程):表示进程是会话首进程,负责管理一个会话中的其他进程;

•L(进程持有锁):表示进程正在持有某个文件锁或者是资源锁,可能在等待其他进程释放锁资源;

进程状态图

进程PID

PID(processid):是进程的唯一身份标识,操作系统给每个进程分配一个数字编号(比如微信的PID可能是1234,浏览器的可能是6789);

PID在Linux中的规则:

•取值:PID是≥0的整数(实际从1开始分配,0号是特殊进程);

•数量限制:系统能创建的进程总数有限,可通过sysctl kernel.pid_max查看上限;

•查看机制:Linux通过 /proc 文件系统暴露进程信息:

   •每个运行的进程对应 /proc/[PID]目录(如 PID=80320对应 /proc/80320);

   •目录内的status文件存储进程详情(PID、名称、运行状态等);

特殊 PID 进程名称 作用与职责
0 号 idle 系统启动后的第一个进程,负责空闲 CPU 调度(无其他进程运行时,idle 进程占用 CPU)。
1 号 init 由 0 号进程创建,负责初始化系统硬件、启动服务、回收孤儿进程(如关机时清理残留进程)。
2 号 kthreadd 负责内核进程调度(管理系统后台的内核级任务,如磁盘 I/O、内存回收)。

进程的相关命令

ps命令

功能:用于查看当前系统中进程的快照信息,包括进程的PID(进程标识符)、所属用户、占用CPU和内存资源情况等;

常用具体命令 选项 功能
ps -ef -e:列出系统中所有进程
-f:以全格式显示进程信息
查看当前所有进程
ps -aux -a:显示所有终端进程
-u:以用户资源视角为中心的格式
-x:显示无终端进程(如后台服务)
展示进程资源占用百分比(如占用CPU百分比、占用内存百分比等)
ps -eo 字段1,字段2... -e:列出系统中所有进程
-o:自定义输出格式
精准提取进程字段(如pid, comm)
ps -l -l:长格式 以长格式查看当前终端进程详细信息

top命令

功能:动态的显示系统中各个进程的资源使用情况,可以实时查看进程的CPU使用率、内存使用量、线程数等,并且能按照不同的指标进行排序;

htop命令

功能:是一个交互式的进程查看工具,相比top具有更友好的用户界面,支持鼠标操作;可以更加直观地展示进程树结构;

kill命令

功能:用于向进程发送信号,最常见的就是用来终止进程。通过指定进程的PID,发送特定的信号让进程执行相应的操作,比如终止、暂停等等;

命令格式 信号编号 对应信号名称 功能说明
kill -l - - 列出系统中所有可用的信号及其编号
kill -2 <pid> 2 SIGINT 向指定进程发送中断信号(相当于 Ctrl+C)
kill -9 <pid> 9 SIGKILL 强制终止指定进程(无法被捕获或忽略)
kill -19 <pid> 19 SIGSTOP 暂停指定进程的运行(相当于 Ctrl+Z,无法被捕获)
kill -18 <pid> 18 SIGCONT 使已暂停的进程恢复运行

killall命令

功能:根据进程名来终止进程,当系统中有多个同名进程需要同时终止时,killall就非常方便;

命令格式 信号编号 对应信号名称 功能说明
killall 进程名 - - 终止所有名为“进程名”的进程(默认发送 SIGTERM)
killall -9 进程名 9 SIGKILL 强制终止所有同名进程
killall -i 进程名 - - 终止前逐一询问确认(交互模式)

pstree命令

功能:以树结构显示进程之间的父子关系,从系统初始化init开始,直观地展示整个系统进程的层次结构;

bg/fg命令

命令格式 功能说明 注意事项
bg [作业号] 将挂起的进程放到后台继续运行 若不指定作业号,默认操作最近一个被挂起的作业;作业号可通过 jobs -l 命令查看获取。
fg [作业号] 把后台运行的进程放到前台终端运行,恢复与终端交互 若不指定作业号,默认将最近一个后台作业调至前台;调至前台后,进程会占据终端输入输出,直到进程结束或再次被暂停。

nice/renice命令

命令 功能 命令格式
nice 启动进程时设置优先级;未指定值时默认优先级为10 nice [-n 优先级值] 要执行的命令
renice 调整已运行进程的优先级;可针对单个进程或某用户的所有进程进行调整 针对单进程:renice 新优先级值 -p 进程PID
针对用户所有进程:renice 新优先级值 -u 用户名

进程的创建

fork函数

项目 说明
所需头文件 #include <sys/types.h>
#include <unistd.h>
原型 pid_t fork(void);
功能 复制当前进程,创建子进程
参数
返回值 成功:父进程返回子进程的 PID(大于0的整数)
成功:子进程返回 0
失败:子进程未被创建,父进程返回 -1,并设置错误码

父子进程内存空间

•父进程在fork产生子进程时,用到了写时拷贝的原则;

•如果父子进程中对内存进行读操作,那么内存不会被重新映射物理内存;

•如果父子进程中的任意一方对内存有写操作时,才会重新映射到新的物理内存;

多进程相关函数

进程号获取函数

getpid函数

项目 内容
所需头文件 #include <sys/types.h>
#include <unistd.h>
原型 pid_t getpid(void);
功能 获取当前进程自身的进程号
参数
返回值 返回当前进程自身的进程号

getppid函数

项目 内容
所需头文件 #include <sys/types.h>
#include <unistd.h>
原型 pid_t getppid(void);
功能 获取当前进程的父进程的进程号
参数
返回值 返回当前进程的父进程的进程号

进程退出函数

exit函数

项目 内容
所需头文件 #include <stdlib.h>
原型 void exit(int status);
功能 正常终止进程,并将 (status & 0377)(按位与运算后的值)返回给父进程。C 标准规定了两个常量:EXIT_SUCCESS 和 EXIT_FAILURE,可传递给 exit()
参数 status 退出状态值。
返回值 无(函数不会返回)。

_exit函数

属性 内容
所需头文件 #include <unistd.h>
原型 void _exit(int status);
功能 立即终止进程,且 status & 0377(按位与运算后的值)会被返回给父进程。
备注 C 标准库为 exit 函数规定了 EXIT_SUCCESS 和 EXIT_FAILURE 常量(通常值分别为 0 和 1),也可传递给 _exit 兼容使用。但 _exit 本身是系统调用,不依赖这些宏。
参数 status 退出状态值。
返回值

资源回收函数

wait函数

类别 内容
所需头文件 #include <sys/types.h>
#include <sys/wait.h>
原型 pid_t wait(int *wstatus);
功能 父进程阻塞,等待任意一个子进程结束;若没有子进程结束,wait会一直等待;当有子进程终止时,它会回收该子进程的资源,并通过wstatus获取子进程的退出状态值。
参数 wstatus 用于存储子进程的退出状态值的内存空间首地址。
- 若为NULL,表示忽略子进程退出时的状态。
- 若不为空,表示将子进程退出状态写入该指针指向的内存,供父进程后续用宏解析。
返回值 - 成功:返回终止子进程的PID。
- 失败:返回 -1,并设置errno以指示错误原因(例如调用进程没有子进程)。

wait函数状态解析宏

子进程正常退出:

•WIFEXITED(wstatus):若子进程是正常终止(调用 exit()/_exit() 或从 main() 返回),则返回 true;

•WEXITSTATUS(wstatus):仅当WIFEXITED为 true 时使用,返回子进程的退出状态码(即exit(n)中的n,取低 8 位);

子进程被信号终止:

•WIFSIGNALED(wstatus):若子进程是被信号终止(如SIGKILL等),则返回 true;

•WTERMSIG(wstatus):仅当WIFSIGNALED为 true 时使用,返回导致子进程终止的信号编号(如9对应SIGKILL);

•WCOREDUMP(wstatus):仅当WIFSIGNALED为 true 时使用,若子进程终止时产生了核心转储文件,则返回 true;

子进程被信号暂停:

•WIFSTOPPED(wstatus):若子进程是被信号暂停(仅在使用 WUNTRACED 标志或子进程被跟踪时有效),则返回 true;

•WSTOPSIG(wstatus):仅当 WIFSTOPPED 为 true 时使用,返回导致子进程暂停的信号编号(如 19 对应 SIGSTOP);

子进程被恢复运行:

•WIFCONTINUED(wstatus):若子进程是通过SIGCONT 信号恢复运行,则返回 true;

waitpid函数

项目 内容
所需头文件 #include <sys/types.h>
#include <sys/wait.h>
原型 pid_t waitpid(pid_t pid, int *wstatus, int options);
功能 父进程等待子进程状态变化并获取其状态信息。允许父进程精准控制子进程的范围,可通过 options 调整等待行为(如阻塞/非阻塞)。
参数 pid 指定要等待的子进程
 • <-1:等待任何进程组ID与进程pid的绝对值相等的子进程
 • -1:等待任何子进程
 • 0:等待任何进程组ID与调用进程相同的子进程
 • >0:等待指定pid的子进程
wstatus 用于存储子进程的退出状态值的内存空间首地址
 • 若为 NULL,表示忽略子进程退出时的状态
 • 若不为空,表示将子进程退出状态写入该指针指向的内存,供父进程后续用宏解析
options 标志位(默认模式是阻塞等待模式 options = 0
返回值 • 成功:返回终止子进程的PID
• 若设置非阻塞且没有子进程退出:返回 0
• 出错(调用进程没有子进程或调用出错):返回 -1,并设置 errno 指示错误原因

options参数

选项常量 作用 具体行为 典型应用场景
0 实现阻塞等待 父进程暂停执行,直到指定的子进程状态发生变化(如退出、被暂停或恢复) 常规子进程同步等待,例如批处理任务中等待子进程完成
WNOHANG 实现非阻塞等待 调用 waitpid 时,若指定子进程未退出,函数立即返回 0,父进程无需阻塞,可继续执行其他任务 父进程需要轮询监控子进程状态,例如守护进程或后台任务管理器
WUNTRACED 捕获子进程暂停状态 当子进程因信号(如 SIGSTOP)停止运行时,waitpid 也能返回该子进程的 PID,父进程可以感知暂停事件 调试器或需要处理子进程暂停逻辑的程序,例如 shell 作业控制
WCONTINUED 捕获子进程恢复运行状态 当已停止的子进程通过 SIGCONT 信号恢复运行时,waitpid 返回该子进程的 PID,父进程可以感知恢复事件 需要跟踪子进程完整生命周期(暂停-恢复)的场景,如进程监控工具或作业控制系统

waitpid函数状态解析宏

子进程正常退出:

•WIFEXITED(wstatus):若子进程是正常终止(调用 exit()/_exit() 或从 main() 返回),则返回 true;

•WEXITSTATUS(wstatus):仅当WIFEXITED为 true 时使用,返回子进程的退出状态码(即exit(n)中的n,取低 8 位);

子进程被信号终止:

•WIFSIGNALED(wstatus):若子进程是被信号终止(如SIGKILL等),则返回 true;

•WTERMSIG(wstatus):仅当WIFSIGNALED为 true 时使用,返回导致子进程终止的信号编号(如9对应SIGKILL);

•WCOREDUMP(wstatus):仅当WIFSIGNALED为 true 时使用,若子进程终止时产生了核心转储文件,则返回 true;

子进程被信号暂停:

•WIFSTOPPED(wstatus):若子进程是被信号暂停(仅在使用 WUNTRACED 标志或子进程被跟踪时有效),则返回 true;

•WSTOPSIG(wstatus):仅当 WIFSTOPPED 为 true 时使用,返回导致子进程暂停的信号编号(如 19 对应 SIGSTOP);

子进程被恢复运行:

•WIFCONTINUED(wstatus):若子进程是通过SIGCONT 信号恢复运行,则返回 true;

文件描述符重定向函数

dup函数

项目 内容
所需头文件 #include <unistd.h>
原型 int dup(int oldfd);
功能 复制一个已有的文件描述符。新文件描述符采用最小未分配的原则分配。
参数 oldfd 旧的文件描述符
返回值 成功:返回新的文件描述符
失败:返回 -1,并设置错误码

dup2函数

项目 内容
所需头文件 #include <unistd.h>
原型 int dup2(int oldfd, int newfd);
功能 复制一个已有的文件描述符 oldfd
新文件描述符使用 newfd 中指定的文件描述符编号
若 newfd 此前已打开,会在重用该描述符前自动静默关闭它
参数 oldfd 旧的文件描述符
newfd 新的文件描述符
返回值 成功:返回新的文件描述符
失败:返回 -1,并设置错误码

进程程序替换函数

exec函数族

所需头文件 #include <unistd.h>
函数原型 int execlp(const char *file, const char *arg, ... /* (char *) NULL */);
int execvp(const char *file, char *const argv[]);
int execl(const char *path, const char *arg, ... /* (char *) NULL */);
int execv(const char *path, char *const argv[]);
int execle(const char *path, const char *arg, ... /*, (char *) NULL, char * const envp[] */);
int execvpe(const char *file, char *const argv[], char *const envp[]);
函数返回值 成功:无返回(进程已被新程序替换)
失败:返回 -1,并设置 errno 来指示错误

execlp函数

项目 内容
所需头文件 #include <unistd.h>
原型 int execlp(const char *file, const char *arg, ... /* (char *) NULL */);
功能 在环境变量 PATH 所指定的目录中查找由 file 参数指定的程序文件,并使用该程序替换当前进程的映像(即当前进程的代码、数据、堆栈等被新程序完全替换,执行流从新程序的入口开始)。
参数 file 要执行的程序文件名(无需提供完整路径,系统会在 PATH 环境变量指定的目录中查找该程序)
arg 传递给新程序的参数列表,需要逐个列出参数,并且以 NULL 作为结束标志
返回值 - 成功:无返回(因为当前进程已被新程序替换,原进程不再存在)。
- 失败:返回 -1,并设置 errno 以指示错误类型。

execvp函数

项目 说明
所需头文件 #include <unistd.h>
原型 int execvp(const char *file, char *const argv[]);
功能 在环境变量 PATH 所指定的目录中查找由 file 参数指定的程序文件,并使用该程序替换当前进程的映像。
参数 file 要执行的程序文件名(无需提供完整路径,系统会在环境变量指定的目录中查找该程序)
argv 指向字符指针数组的指针(数组最后一个元素必须是 NULL
返回值

- 成功:无返回(进程已被新程序替换)。
- 失败:返回 -1,并设置 errno 以指示错误类型。

特殊进程

孤儿进程

定义:当一个进程的父进程先于它终止,该进程就会成为孤儿进程;

产生原因:父进程意外崩溃、被强制终止(如kill -9),或父进程主动退出但未正确处理子进程;

特点:

•失去父进程后,会被系统的“祖先进程”(linux中是init或system,PID=1)收养;

•仍能正常运行,完成自身任务后会正常终止,不会占用额外资源;

影响:

•本身是系统正常处理机制的结果,无负面影响,反而避免了进程成为“无主进程”;

•例如:若父进程因bug崩溃,子进程被init收养后可继续提供服务;

僵尸进程

定义:进程终止后,内核未释放其进程控制块(PCB),该进程状态变为Z(僵尸态),成为僵尸进程;

产生原因:父进程未调用wait()或waitpid()等系统调用,读取子进程的退出状态(如退出码、终止原因),导致内核无法回收PCB;

特点:

•已终止运行,不再执行任何代码,但PCB仍占用内存资源(如PID、退出状态);

•通过ps命令中显示状态为Z或者是Z+(僵尸态),名称可能为<defunct>;

影响:

•系统PID数量有限,大量僵尸进程会耗尽PID资源,导致新进程进行无法创建;

•不占用用户空间的内存数据段,但内核空间的PCB资源仍被占用且无法使用;

处理方式:

•预防:父进程调用wait()/waitpid()主动回收子进程状态;

•清除:kill-9无法直接杀死僵尸进程(其已终止,无运行实体);

父进程未处理,可终止父进程(僵尸进程被1号进程收养,1号进程会定期回收其PCB);

守护进程

定义:运行在后台的特殊进程,独立于控制终端,用于持续提供系统服务;

设计目的:不受用户登录/注销影响,长期稳定运行(如网络服务、定时任务);

特点:

•脱离终端:无控制终端,避免终端关闭导致进程终止;

•后台运行:通过ps命令查看状态通常为S(休眠),名称多以d结尾(如httpd、systemd);

•父进程为1号进程:启动后会与原本父进程脱离,被1号进程收养;

•环境干净:默认不继承终端信号,工作目录通常为\,文件描述符(如stdin/stdout/stderr)被关闭或重定向到/dev/null;

守护进程创建流程

•父进程fork( )后退出,子进程成为孤儿进程(被1号收养);

•子进程调用setsid( )函数创建新会话,脱离原终端控制;

•调用chdir( )函数改变进程的工作目录到一个不会被删除和卸载的目录下;

•使用umask( )函数修改创建文件的掩码;

•关闭所有从父进程继承过来的文件描述符集合;

•使用dup( )或者是dup2( )将标准输入/标准输出/标准出错都重定向到文件中;

•开启自己的服务;

代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main() {
    pid_t pid = fork();
    if (pid < 0) exit(1);
    if (pid > 0) exit(0);  // 父进程退出

    // 子进程成为孤儿,调用 setsid 成为新会话首领
    if (setsid() < 0) exit(1);

    // 再次 fork,防止意外获得终端
    pid = fork();
    if (pid < 0) exit(1);
    if (pid > 0) exit(0);

    // 改变工作目录
    chdir("/");

    // 重设文件权限掩码
    umask(0);

    // 关闭所有文件描述符(这里简单关闭标准三剑客)
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

    // 重定向到 /dev/null
    open("/dev/null", O_RDWR);  // 0
    dup(0);                     // 1
    dup(0);                     // 2

    // 守护进程的主逻辑
    while (1) {
        // 做一些后台工作,比如每秒记录一次时间
        syslog(LOG_INFO, "Daemon is running...");
        sleep(10);
    }
    return 0;
}

setsid函数

项目 内容
所需头文件 #include <sys/types.h>
#include <unistd.h>
原型 pid_t setsid(void);
功能 创建一个新会话,并让调用该函数的进程成为这个新会话的首进程,同时也成为新进程组的组长
参数
返回值 成功:返回调用进程的新会话标识符
失败:-1,重置错误码

chdir函数

项目 内容
所需头文件 #include <unistd.h>
原型 int chdir(const char *path);
功能 将调用进程的当前路径修改为参数所指定的目录
参数 path 新的工作目录
返回值 成功:0
失败:-1,并设置错误码

umask函数

项目 内容
所需头文件 #include <sys/types.h>
#include <sys/stat.h>
原型 mode_t umask(mode_t mask);
功能 修改进程的文件创建掩码(权限掩码)
参数 mask

新的掩码值

实际文件权限 = ~mask & 0666
实际目录权限 = ~mask & 0777

返回值 总是成功,返回之前的掩码值

三者的核心区别

对比维度 孤儿进程(Orphan Process) 僵尸进程(Zombie Process) 守护进程(Daemon Process)
定义 父进程先于子进程退出,被子进程被1号进程(init/systemd)收养的进程 子进程先退出,但父进程未调用 wait/waitpid 回收其PCB,导致进程状态为 Z 的进程 脱离控制终端、在后台长期运行的系统服务进程(如 sshd、nginx)
产生原因 父进程意外退出或主动退出,未等待子进程 子进程退出后,父进程未调用 wait/waitpid 回收其退出状态 程序主动调用 setsid 等函数创建,脱离终端并后台运行
进程状态 正常运行状态,PPID=1(被 init 收养) 僵尸状态,标记为 <defunct> 后台运行状态,无控制终端,名称常以 d 结尾(如 httpd
资源占用 占用正常进程资源(代码/数据/PCB) 仅占用 PCB 资源(PID、退出状态),不占用代码段/数据段 占用正常进程资源,长期稳定运行
危害 无直接危害,被1号进程正常管理 大量积累会耗尽 PID 资源,导致新进程无法创建 无危害,是系统正常运行的必要服务(如网络服务、定时任务)
处理方式 无需手动处理,1号进程会自动回收其资源 父进程调用 wait/waitpid 主动回收;或终止父进程,由1号进程回收 无需处理,随系统启动而启动、终止而终止,可通过 systemctl 等工具管理
典型场景 父进程未等待子进程就退出(如脚本中后台运行的子进程) 父进程长期运行且未处理子进程退出(如服务器程序漏洞) 系统服务(如 sshd、crond、nginx)

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐