一.孤儿进程
1.定义:当一个进程的父进程先于它终止,这个进程就会成为孤儿进程;
2.产生原因:父进程意外崩溃、被强制终止(如kill -9),或父进程主动退出但未正确处理子进程;
3.特点:
1.失去父进程后,会被系统的“祖先进程”(linux中是init或system,PID=1)收养;
2.仍能正常运行,完成自身任务后会正常终止,不会占用额外资源;
4.影响:
本身是系统正常处理机制的结果,无负面影响,反而避免了进程成为“无主进程”;
例如:若父进程因bug崩溃,子进程被init收养后可继续提供服务;
二.僵尸进程
1.定义:
进程终止后,内核未释放其进程控制块(PCB),该进程状态变为Z(僵尸态),成为僵尸进程;
2.产生原因:
父进程未调用wait()或waitpid()等系统调用,读取子进程的退出状态(如退出码、终止原因), 导致内核无法回收PCB;
3.特点:
已终止运行,不再执行任何代码,但PCB仍占用内存资源(如PID、退出状态);
通过ps命令中显示状态为Z或者是Z+(僵尸态),名称可能为<defunct>;
4.影响:
系统PID数量有限,大量僵尸进程会耗尽PID资源,导致新进程进行无法创建;
不占用用户空间的内存数据段,但内核空间的PCB资源仍被占用且无法使用;
5.处理方式:
预防:
父进程调用wait()/waitpid()主动回收子进程状态;
清除:
kill -9无法直接杀死僵尸进程(其已终止,无运行实体); 父进程未处理,可终止父进程(僵尸进程被1号进程收养,1号进程会定期回收其PCB);
三.守护进程
1.定义:运行在后台的特殊进程,独立于控制终端,用于持续提供系统服务;
2.设计目的:不受用户登录/注销影响,长期稳定运行(如网络服务、定时任务);
3.特点:
脱离终端:无控制终端,避免终端关闭导致进程终止;
后台运行:通过ps命令查看状态通常为S(休眠),名称多以d结尾(如httpd、systemd);
父进程为1号进程:启动后会与原本父进程脱离,被1号进程收养;
环境干净:默认不继承终端信号,工作目录通常为\,文件描述符(如stdin/stdout/stderr)被关闭或重 定向到/dev/null;
1.守护进程创建流程
1.父进程fork()后exit()退出,子进程成为孤儿进程(被1号进程收养)
2.子进程调用setsid()函数创建新会话,脱离原终端控制
3.调用chdir()函数改变进程的工作目录到一个不会被删除和卸载的目录下
4.使用umask()函数修改创建文件的掩码
5.关闭所有父进程继承过来的文件描述符集合 close()
6.使用dup()或者dup2()将标准输入/标准输出/标准出错都重定向到文件中
7.开启自己的服务
2.setsid()函数
#include <sys/types.h>
#include <unistd.h>
pid_t setsid(void);
创建一个新会话,并让调用该函数的进程成为这个新会话的首进程,同时也成为新进程组的组长
返回值:
成功:返回调用进程的新会话标识符
失败:-1,重置错误码
3.chdir()函数
#include <unistd.h>
int chdir(const char *path);
将调用进程的当前路径修改为参数所指定的目录
path 新的工作目录
返回值:
成功:0
失败:-1,重置错误码
4.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号进程收养的进程。 | 子进程先退出 父进程未调用wait/waitpid回收其PCB导致进程状态为Z的进程 | 脱离控制终端,在后台长期运行的系统服务进程 (如sshd,nginx) |
| 产生原因 | 父进程意外退出或主动退出 未等待子进程 | 子进程退出后 父进程未调用wait/waitpid回收其退出状态 | 程序主动调用setpid()等函数创建脱离终端并后台运行 |
| 进程状态 | 正常运行状态,ppid=1 | 僵尸状态,标记为<defunct> | 后台运行状态,无控制终端,名称常以d结尾 (如httpd) |
| 资源占用 | 占用正常进程资源 (代码/数据/ PCB) | 仅占用PCB资源(PID、退出状态) 不占用代码段/数据段 | 占用正常进程资源, 长期稳定运行 |
| 危害 | 无直接危害 被1号进程正常管理 | 大量积累会耗尽PID资源 导致新进程无法创建 | 无危害,是系统正常运行的必要服务 (如网络服务,定时任务) |
| 处理方式 | 无需手动处理 1号进程会自动回收其资源 | 父进程调用wait/waitpid主动回收; 终止父进程,由1号进程回收。 | 无需处理,随系统启动而启动,终止而终止,可通过systemctl等工具管理 |
| 典型场景 | 父进程未等待子进程就退出 如:脚本中后台运行的子进程 | 父进程长期运行且未处理子进程退出 如:服务器程序漏洞 | 系统服务(如sshd,crond,ngix) |