【Linux】孤儿进程和僵尸进程

现在有如下程序输出父子进程pid和ppid,后面几个部分都围绕此程序:

 #include<stdlib.h>
 #include<string.h>
 #include<unistd.h>
 int main()
 {
     int n=0;
     char*s = NULL;
     pid_t pid = fork();
     if(pid==-1)
     {
         exit(0);
     }
     if(pid==0)
     {
         n=3;
         s="child";
     }
  else
     {
         n=6;
         s = "parent";
     }
     for(int i=0;i<n;i++)
     {
         printf("s=%s,pid=%d,ppid=%d\n",s,getpid(),getppid());
//getpid()当前进程id号,getppid获得父进程的id号
     }
 }

关于命令提示符:

每当父进程结束,bash会打印一行命令提示符提示进程结束让我们继续输入,子进程结束没有单独的提示符

子进程输出3次,父进程输出6次,结束后可以看到输出了这行提示


但如果将程序改为子进程输出6次,父进程输出3次:可以看到,父进程输出完后产生了提示符,此时子进程还没结束,在其后面继续输出,子进程结束后没有命令提示符。


所有进程之父——bash

通过获取pid和ppid,可以发现,虽然每次父进程的pid号都不一样,但其父进程id号都是3311,3311即为bash的id号(我的电脑中),终端中运行的第一个进程就是bash,它是所有新进程的父进程

全新进程的产生有两步:1.fork(bash赋值自己)2.exec(替换成需要的进程)

(ps -f的父进程也是bash)


孤儿进程

当子进程输出6次,父进程输出3次时,可以发现,当父进程结束(输出命令提示符)之后,子进程的ppid改变了,不再是之前父进程的pid

这时候(父进程先结束,没有父进程)的子进程被称为孤儿进程

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。
孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

系统将为孤儿进程找一个新的父进程,早期为pid为1的init进程,但是由于目前内核发生变化,使用的不是这个了。

僵尸进程

僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。

子输出3次,父输出6次,当子进程结束后其详情中会有一个标识<defunct>,已经死了的。

这是因为子进程先于父进程结束,且父进程没有获取子进程的退出码。

退出码:exit(0) return 0,这个0就是退出码,退出码会被写入自己的PCB中,让父进程知道子进程的状态:是正常结束还是异常结束。PCB不会因进程结束而删除,它会一直保留到父进程获取它。

僵尸进程导致的问题:

因为僵尸进程永远不会再执行了,但是其PCB没删。

1.内存空间没有释放,如果长期这样消耗,会逐渐耗完内存空间;

2.pid号一直被占用,无法复用,软件层的资源也被占。

处理方法:

wait()获取子进程的退出码,处理僵尸进程。

加在父进程执行的位置:

它把退出码左移了8位存放,其他位置存其他的内容

孤儿进程被其他进程收养,就是为了获取这个进程的退出码,这样孤儿/僵尸进程也可以被释放;

系统进程都处理好了,不会产生僵尸进程。

wait()会阻塞一下进程,使子进程运行完了再执行父进程。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曦樂~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值