孤儿进程

孤儿进程

产生原因

父进程先于子进程退出,子进程就变了孤儿进程

代码模拟产生孤儿进程

在这里插入图片描述

当父进程退出的时候,子进程依旧在循环中,这种父进程先于子进程退出的,子进程就变成了孤儿进程。

我们来看一下代码执行的效果:

在这里插入图片描述
我们来看一下这个父子进程的关系:
在这里插入图片描述

6610号进程由1068号进程创建,6611号进程由6610号进程创建,那我们是如何让创建出6610号进程的呢?

我们解释一下在命令行当中启动一个进程的原理:命令行解释器的进程,创建出子进程,让子进程进行进程程序替换,替换为目标程序。为什么要进行程序替换呢?因为父进程在调用fork函数创建出来的子进程,其代码段是和父进程完全相同的,当我们需要子进程去执行和父进程不同的功能,就需要进行进程程序替换,将子进程的代码段替换为目标程序。

此时,6611号进程的父进程是6610号进程,也就是把它创建出来的那个进程,但是我们来看看下面循环打印的语句:

在这里插入图片描述

下面是一直在循环打印的,趁着循环的时候我们来看一下进程信息:

在这里插入图片描述

已经找不到父进程了,说明父进程已经退出了。这个时候我们的子进程就变成了孤儿进程。也就是说,上面一直循环打印那句话的进程是孤儿进程打印出来的。

我们仔细观察,发现此时打印的ppid是1,说明子进程此时的父进程不是创建它的6610号进程,而是1号进程。说明没有“亲生父亲”的子进程会被1号进程“领养”。

一号进程

那什么是1号进程呢?

1号进程:操作系统的init进程,操作系统很多进程都是由1号进程创建出来的。
孤儿进程的父进程变成了1号进程,同时我们也知道,子进程退出的时候,由父进程回收子进程的退出状态信息,此时孤儿进程被1号进程领养后,退出的状态信息由1号进程进行回收。

前台进程、后台进程

在这里插入图片描述

当orphan的子进程在运行的时候,我们在命令行解释器中输入其他命令,也可以执行,这是为什么呢?

我们来看一下此时orphan的子进程的进程状态:

在这里插入图片描述

我们现在来创建一个新的进程,举个例子,来看看进程运行的过程什么情况下不能在命令行中输入命令,创建新的进程。
程序代码:
在这里插入图片描述

我们看一下执行结果:

在这里插入图片描述

在程序循环执行打印的时候,我们输入其他命令是完全不起作用的,为什么呢?
我们来看一下程序的进程状态信息:

在这里插入图片描述

对比一下上面的和下面的进程状态信息最大的不一样就是多了一个“+”号,带有“+”号的是前台进程,不带“+”号的是后台进程。

前台进程:阻塞bash运行的进程称为前台进程,反之,不阻塞的称为后台进程。

联系到我们上面提到的在命令行启动一个进程的原理,前台进程阻塞了bash运行,bash就是命令行解释器的进程,命令行解释器的进程被阻塞,bash就不能创建新的子进程,不阻塞的话,在命令行解释器输入命令的时候,bash就能先fork一个子进程出来,再进行进程程序替换,就能执行新的命令了。
所以我们就能明白上面两个例子了,第一个例子是因为bash的创建的子进程退出了,且这个子进程创建出来的子进程变成了孤儿进程,同时也是后台进程,所以就没有能阻塞bash的进程了,bash就能解释新的命令了;第二个例子bash创建出来的子进程一直在循环中,一直是前台进程,bash被阻塞,就不能去创建新的进程,不能解释新的命令了。

我们给出一个结论:在命令行当中运行的进程,一般情况下都是要阻塞bash进程的运行的。

孤儿进程有危害吗?

首先给出结论:孤儿进程没有任何危害,1号进程会回收孤儿进程的退出状态信息。

给出一段代码来验证一下:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 {
  5   pid_t ret = fork();
  6   if (ret < 0){
  7     return 0;
  8   }else if(ret == 0){
  9     //child
 10     int count = 10;
 11     while(count--){
 12       printf("I am child,pid is %d,ppid is %d\n",getpid(),getppid());
 13       sleep(2);
 14     }
 15   }else{
 16     printf("I am father,pid is %d,ppid is %d\n",getpid(),getppid());
 17   }
 18   return 0;                                                                              
 19 }
~

看一下运行结果:
在这里插入图片描述

在25712号进程运行的时候查看进程状态信息:

在这里插入图片描述

这个时候,创建25712的父进程25711已经退出了,所以我们的25712号进程的父进程变成了1号进程。
孤儿进程执行完之后,如果它的退出状态信息没有人回收,就可能变成僵尸进程,我们来看一下它结束之后的进程状态信息:

在这里插入图片描述

很明显,孤儿进程没有变成僵尸进程,它的退出状态信息被1号进程回收了,所以我们说孤儿进程是没有危害的。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值