进程——孤儿进程 僵尸进程

本文深入探讨了孤儿进程和僵尸进程的概念,通过具体代码示例展示了这两种进程如何在Linux环境下产生,解释了它们的生命周期及对系统资源的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

孤儿进程

概念:
父进程先于子进程退出
子进程没有父进程获取自身的退出状态,也就变成了孤儿进程
但是,所有的孤儿进程都被一号(init)进程所收养,由一号进程作为所有孤儿进程的父进程,负责孤儿进程的资源释放
产生孤儿进程代码:

 #include<stdio.h>                                                                                                 
 #include<unistd.h>                                                                                                                                                                                                                 
 int main()                                                                                                        
 {                                                                                                                 
	 pid_t pid = fork();                                                                                             
	 if(pid < 0){                                                                                                    
	     perror("fork");                                                                                               
	 }                                                                                                            
	 else if(pid == 0){                                                                                              
	 	 printf("child  pid = %d, ppid = %d\n", getpid(), getppid());                                               
		 sleep(8);                                                                                                     
		 printf("child  pid = %d, ppid = %d\n", getpid(), getppid());                                                  
	 }                                                                                                               
	 else{                                                                                                           
	    sleep(3);                                                                                                     
	    printf("father  pid = %d, ppid = %d\n", getpid(), getppid());                                                 
	 }                                                                                                               
	 return 0;                                                                                                       
 }

在这里插入图片描述

分析:首先让父进程睡眠3秒,那么子进程打印出第一句之后,进入8秒的休眠期,此时子进程的父进程id我们可以看到是父进程的id,三秒之后,父进程退出(孤儿进程形成条件) 8秒之后,子进程退出时,可以看到它的父进程id已经变成了 1, 也就是说明孤儿进程会被一号进程所领养!
:孤儿进程在系统后台运行

僵尸进程

概念:
由于子进程先于父进程退出,
子进程退出时,为了保存自己的退出状态,等待父进程获取自己的退出状态,释放子进程资源
但是由于父进程并没有关心子进程退出,导致子进程一直占用着系统资源,不释放,直到父进程读取子进程退出状态
也就导致子进程变成了僵尸进程

产生僵尸进程代码:

 #include<stdio.h>                                                                                                 
 #include<unistd.h>                                                                                                                                                                                                                 
 int main()                                                                                                        
 {                                                                                                                 
	 pid_t pid = fork();                                                                                             
	 if(pid < 0){                                                                                                    
	     perror("fork");                                                                                               
	 }                                                                                                            
	 else if(pid == 0){                                                                                                                                          
		 sleep(2);                                                                                                     
		 printf("child  pid = %d, ppid = %d\n", getpid(), getppid());                                                  
	 }                                                                                                               
	 else{                                                                                                           
	    sleep(5);                                                                                                     
	    printf("father  pid = %d, ppid = %d\n", getpid(), getppid());                                                 
	 }                                                                                                               
	 return 0;                                                                                                       
 }

在这里插入图片描述

分析:
我们可以由代码和图片,可以知道,在前两秒时间里,子进程和父进程同时处于运行状态,当两秒之后子进程退出,此时父进程还未退出,未获取子进程的退出状态,形成了产生僵尸进程的条件,结果可以看到,在此状态下,子进程的状态变为Z,也就是僵尸状态,知道父进程也退出之后,其退出状态才被父进程获取,从而结束掉父子两个进程!

thanks!!!

### 僵尸进程 僵尸进程是指那些已经完成执行但仍然存在于系统中的进程。这些进程实际上已经终止,但由于其父进程尚未调用 `wait()` 或者类似的函数来获取子进程的状态信息并清理资源,因此它们的进程控制块(PCB)依然保留于操作系统中[^4]。这种状态下的进程不会消耗任何 CPU 资源,但却会占用一定的内存空间以及进程表条目。 如果存在大量未处理的僵尸进程,则可能导致系统的可用进程 ID 数量耗尽,从而影响新进程的创建。此外,长期存在的僵尸进程也会浪费有限的操作系统资源[^3]。 ### 孤儿进程 孤儿进程通常是因为父进程提前结束运行或者是由于其他原因未能正常管理自己的子进程所造成的现象。当某个子进程失去它的父进程时——也就是说,在该子进程生命周期内,其原本所属的父进程已先行消亡,则此子进程便成为了一个孤儿进程[^1]。一旦变成孤儿进程之后,它会被初始化进程 (init process),即 PID 为 1 的特殊进程收养,并继续执行直到自己也退出为止。 值得注意的是,孤儿进程并不会对系统性能构成威胁,因为 init 进程会自动接管所有的孤儿进程并通过调用 wait 函数回收他们的资源[^2]。 ### 守护进程 守护进程是一种在后台持续运行的服务型程序,即使用户登录到系统后又注销了,这类服务依旧保持活跃状态而不受影响。它们一般用于提供某种特定功能给整个计算机环境使用,比如网络服务器监听端口请求、定时任务调度器等等。为了实现这一点,守护进程往往会在启动初期经历一系列特殊的设置操作,包括但不限于关闭标准输入/输出流、改变当前工作目录至根路径下以防干扰文件系统卸载过程、忽略终端挂起信号(SIGTTOU/SIGTTIN)等措施以确保完全脱离交互式的 shell 控制界面转入纯后台模式运作下去。 ### 区别与联系 - **僵尸进程** 和 **孤儿进程** 都属于异常情况的结果,其中前者因父进程未能及时清除已完成工作的子进程而导致;后者则是源于父子关系断裂后的自然产物。两者主要差异在于:僵尸进程虽然名义上还活着但实际上无法再做更多事情只是等待被彻底销毁而已;而孤儿进程则可以由新的监护人接手进而恢复正常运转直至自行终结。 - 对比之下,**守护进程** 是一种设计上的主动选择而非错误状况引发的现象。它是专门为某些目的长时间驻留于背景之中默默奉献力量的一种机制。不像前两种类型那样可能带来负面效应,相反地,合理运用守护进程能够极大地提升工作效率和服务质量。 ```bash ps aux | grep 'defunct' # 查看系统中存在的僵尸进程 top -b -n 1 | grep '<defunct>' # 另外一种查看方式 pstree -p $(pgrep -f parent_process_name) # 显示指定父进程中包含的所有子进程树形结构,有助于定位潜在问题源头 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值