Linux系统【三】回收子进程
孤儿进程
父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为init
进程,则称init
进程领养孤儿进程。现在好像是用户进程中的system
进程。
僵尸进程
进程终止,父进程不进行回收,自己成残留资源(PCB)存放在内核中,变成僵尸进程。
子进程死亡以后会将自己占用的内存(4G)释放,但是会将死亡信息放在自己的PCB中,希望父进程调用得到子进程的死亡信息以后再清除PCB。需要注意的是僵尸进程是不能使用kill
命令清除掉的,因为kill
命令知识用来终止进程的,而僵尸进程已经终止。这就要求我们手动回收子进程。
这里的僵尸进程特别指的是父进程没有结束而子进程已经结束,如果父进程结束就算我们不手动回收也会自动回收(实际过程是父进程结束以后没有回收的子进程变成孤儿进程被init
进程或者system
进程回收)
wait函数回收子进程
一个进程在终止时会关闭所有的文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,内核在其中保存了一些信息:如果是正常终止则保存着退出状态,如果是异常终止则保存着导致该进程终止的信号是哪个。这个进程的父进程可以调用wait
或者waitpid
获取这些信息,然后彻底清除这个进程。
shell下一个进程的退出状态可以用特殊变量$?
查看,因为shell
是他的父进程,当它终止时shell调用wait
或者waitpid
得到它的退出状态同时彻底清除掉这个进程。
wait函数可以回收子进程终止信息,该函数有三个功能:
- 阻塞等待子进程退出:如果子进程没有结束父进程不会干其他的事情
- 回收子进程残留的
PCB
资源 - 获取子进程结束状态(退出原因)
一次wait函数只能清除一个子进程
pid_t wait(int *status);
返回值:如果成功返回子进程ID,如果失败返回-1
(没有子进程的话就会报错)
status保存结束状态
- 进程正常结束
WIFEXITED(status) 为非0说明是正常退出
WEXITSTATUS(status)如果上面宏为真,使用这个宏获取进程退出状态(exit的参数)
- 进程异常终止(收到信号终止,例如段错误、总线错误、浮点数例外错误)
WIFSIGNALED(status) 为非0,说明程序异常终止
WTERMSIG(status)如果上面宏为真使用此宏 取得使得进程终止的那个信号的编号
- 进程处于暂停状态
WIFSTOPPED(status) 为非0,进程处于暂停状态
WSTOPSIG(status) 如果上述宏为真,取得使得进程暂停的那个信号的编号
WIFCONTINUED(status) 为真表示进程暂停后已经继续运行
waitpid函数
一次waitpid函数只能清除一个子进程,和wait
函数类似
pid_t waitpid(pid_t pid,int* status,int options)
第一个参数用于指定需要回收的进程ID,第三个参数可以设置不阻塞回收,即仅仅返回一个状态
pid
:
- 大于0 表示回收的子进程ID
- -1 表示回收任意子进程(相当于wait)
- 0 回收当前调用
waitpid
一个组的任意子进程,在一般情况下和-1
相同 - <-1 回收指定进程组内的任意子进程,
-进程组ID
,进程组ID可以用ps ajx
查看
options
: - 当参数为
WNOHANG
,非阻塞回收,轮询查看 - 当参数为
0
的时候,阻塞回收,相当于wait
返回值:
- 成功返回子进程ID
- 失败返回-1
- 如果轮询访问回收子进程的时候子进程没有结束则返回0
例如:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>int main(int argc, char* argv[])
{int n=5;if(argc>2){printf("too many arguments\n");exit(1);}else if(argc==2){n = atoi(argv[1]);}int pi;pid_t p,q;for(pi=0;pi<n;++pi){p=fork();if(0 == p){break;}else if(3 == pi){q = p;}}if(n==pi){printf("I am parent,pid = %d\n",getpid());//删除单个子进程//waitpid(q,NULL,0);//循环删除子进程//while(-1!=waitpid(-1,NULL,0));//非阻塞删除子进程pid_t tid;do{tid=waitpid(-1,NULL,WNOHANG);}while(tid != -1);printf("OK\n");while(1);}else{printf("I am child,pid = %d\n",getpid());}return 0;
}
Linux系统【三】回收子进程相关推荐
- Problem 64 如何设置Linux系统内存回收的阀值?
Problem 64 如何设置Linux系统内存回收的阀值? Ans: Linux内核的策略是最大程度的利用内存cache 文件系统的数据,提高IO速度,虽然在机制上是有进程需要更大的内存时,会自动释 ...
- Linux系统三步安装QQ
Linux系统三步安装QQ 第一步:网页下载Linux版QQ 第二步:在安装包所在位置打开终端 第三步:安装 第一步:网页下载Linux版QQ 下载地址:https://im.qq.com/linux ...
- 享受便利的应用方式—Linux系统三则超酷技巧
Linux下修改MAC地址 MAC地址是网卡的物理地址,在Windows系统下,我们可以通过修改注册表的方法,骗过系统,修改MAC地址.其实在Linux下也可更改MAC地址: 1.关闭网卡设备 /sb ...
- 深度linux系统 -- 三步安装nodejs
第一步:准备工作: 系统版本:deepin 15.10.1 桌面版 64位 nodejs 下载地址:https://nodejs.org/zh-cn/ 我下载的是 10.16.0 第二步 解压 ...
- 【Linux知识点】Linux 系统三种分区方案
通用分区方案: /boot 引导分区(200M) swap 交换分区(当内存不够用的时候,将硬盘中的空间充当内存使用), 内存 < 8G:建议交换分区大小 = 内存大小的 1.5 倍 内存 &g ...
- 远程登录linux进程的状态_Linux实操篇 - 远程登录到Linux系统
一.为什么要远程登录Linux系统 在我们日常开发中,具体情况如下: Linux服务器是项目组共享的; 正式上线的项目运行在公网上; 综上所述,我们需要通过工具远程登录到服务器进行项目管理; 二.远程 ...
- 嵌入式Linux设备驱动程序开发指南3(构建Microchip SAMA5D2嵌入式 Linux系统)——读书笔记
构建Microchip SAMA5D2嵌入式 Linux系统 三.构建Microchip SAMA5D2嵌入式 Linux系统 3.1 获取驱动代码 3.2 配置编译 3.2.1 bootstrap编 ...
- linux锁定系统时间设置,设置linux系统时间的方法
尝试了好多,都是因为权限问题失败,但是总结出了几种思路: 1 通过linux指令进行设置: date -s "20091112 18:30:50" &&hwcloc ...
- Linux系统编程--3(exec 函数族,僵尸进程和孤儿进程,wait和wait_pid回收子进程)
exec 函数族 fork 创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支) ,子进程往往要调用一种 exec 函数以执行另一个程序.当进程调用一种 exec 函数时,该进程的用户 ...
最新文章
- 树的分类,特性与遍历
- Ubuntu中设置防火墙的开启与关闭
- 下位机和上位机是什么意思_焊锡机是什么?焊锡机有几种分类?
- linux操作系统下建用户,如何用Linux操作系统批量建立用户的shell
- PHP递归写入MySQL无限级分类数据
- android java文件_android 项目下文件的作用
- windows10安装AWVS
- stm32用tft-lcd 显示自定义大小的字体
- STM32战舰USB转串口驱动
- 详细解说iexplore.exe
- win11系统中文名改英文名(win11、win10修改用户名)超详细图文
- 动漫Hello World
- ajax把参数放body里,ajax请求-jquery发送ajax请求,参数怎么放到http请求的body里面...
- VUE Router Error matched of undefined
- 未明学院:被腾讯群面虐完后,我找到了未来的方向…
- 6个月融资超50亿元,云计算创业团队正做得风生水起?
- 用APICloud开发仿微信聊天App制作经验分享
- 航天信息C48服务器,CSPICE航天信息系统的解析与使用--详细介绍
- 安卓跳转应用市场评论
- java贪吃蛇代码idea_IntelliJ idea使用笔记 - 贪吃蛇学院-专业IT技术平台