孤儿进程与僵尸进程

简介: 孤儿进程与僵尸进程

父进程与子进程的生命周期一般是不相同的,父子进程互有长短,这就引出了两个问题:孤儿进程僵尸进程的产生。


孤儿进程

首先看一段示例代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, const char *argv[]) {
  pid_t pid;
  pid = fork();
  if (pid < 0) {
    perror("fork error");
    return -1;
  } else if (pid == 0) {
    /* child */
    printf("The child process, id = %d parent id = %d\n", getpid(), getppid());
    while(1);
  } else {
    /* parent */
    printf("The parent process, id = %d\n", getpid());
  }
  return 0;
}点击复制复制失败已复制


编译并执行,结果如下所示:

$ gcc main.c && ./a.out 
The parent process, id = 60297
The child process, id = 60298 parent id = 60297点击复制复制失败已复制


提示

接下来的部分和原版产生了偏差,主要差别在于父进程ID哪里,详见:原版


代码分析:上述案例代码,主进程运行完成之后就退出了,而子进程被 while(1) 死循环阻塞了。接下来查看进程信息:

$ ps axj | grep a.out
   PPID     PID    PGID     SID TTY        TPGID STAT   UID   TIME COMMAND
   1113   60298   60297   56354 pts/0      60972 R     1000   2:30 ./a.out
$ ps axj | grep 60297       
   PPID     PID    PGID     SID TTY        TPGID STAT   UID   TIME COMMAND
   1113   60298   60297   56354 pts/0      61250 R     1000   3:30 ./a.out点击复制复制失败已复制


可以发现, 60279 这个父进程找不到,相应的父进程却变成了 1113 。子进程处于运行态R ),此子进程就是一个孤儿进程


接下来看看 1113 这个进程是什么东西

$ ps axj | grep 1113     
   PPID     PID    PGID     SID TTY        TPGID STAT   UID   TIME COMMAND
      1    1113    1113    1113 ?             -1 Ss    1000   0:00 /lib/systemd/systemd --user点击复制复制失败已复制


可以看出这时 systemd 进程。在这这里需要说明一点的是,进程在退出时,通常由该进程的父进程对其资源进行回收及释放资源。如果该进程的父进程提前退出,那么此时该进程将失去了“父亲”,则成为了“孤儿”。


僵尸进程

僵尸进程其实是进程的一种状态,即僵尸态。在进程的状态笔记中介绍了僵尸进程的形成。进程的僵尸态和死亡态很接近。唯一不同的是,死亡进程,即进程退出,释放所有资源;而僵尸进程,即进程退出但没有释放资源。因此在实际的编程过程中,应尽量关注这一点,避免产生僵尸态的进程,因为僵尸进程不执行任何任务,却占有系统资源。如果僵尸进程太多,就会导致系统浪费,示例如下:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, const char *argv[]) {
  pid_t pid;
  pid = fork();
  if (pid < 0) {
    perror("fork error");
    return -1;
  } else if (pid == 0) {
    /* child */
    printf("The child process, id = %d parent id = %d\n", getpid(), getppid());
  } else {
    /* parent */
    printf("The parent process, id = %d\n", getpid());
    while(1);
  }
  return 0;
}点击复制复制失败已复制


编译并执行:

$ gcc main.c && ./a.out 
The parent process, id = 65560
The child process, id = 65561 parent id = 65560
点击复制复制失败已复制


注意

终端可没有退出哦!


接下来查看进程信息:

$ ps axj | grep a.out
   PPID     PID    PGID     SID TTY        TPGID STAT   UID   TIME COMMAND
  56354   65560   65560   56354 pts/0      65560 R+    1000   0:51 ./a.out
  65560   65561   65560   56354 pts/0      65560 Z+    1000   0:00 [a.out] <defunct>点击复制复制失败已复制


可以看出,如果父进程不退出子进程退出,此时父进程不会主动回收子进程的资源,子进程成为僵尸进程(状态为: Z+Z 表示僵尸态)。僵尸进程的产生,往往是因为父进程没有对子进程的资源进行回收处理。因此为了避免这样的结果出现,程序需要在子进程选择退出时,由父进程进行资源的回收处理。

目录
相关文章
|
1天前
|
Linux
网络编程之信号(处理僵尸进程的终极办法)之初识信号捕捉器
接着我们之前的管道所提出来的问题() 在创建子进程之后,子进程究竟何时终止????调用waitpid函数后还要无休止的等待子进程终止吗???”,这显然会是一个问题。因为父进程往往与子进程一样繁忙,因此我们不能只调用waitpid函数来等待子进程终止。那么我们应该怎么办呢??? 信号闪亮登场!!!!!
32 0
|
1天前
|
Linux C语言
Linux: 僵尸进程究竟是什么?有什么危害?
Linux: 僵尸进程究竟是什么?有什么危害?
38 0
|
1天前
|
弹性计算 Shell Linux
查找Linux 系统中的僵尸进程
【4月更文挑战第29天】
7 0
|
1天前
|
弹性计算 Shell Linux
查找 Linux 系统中的僵尸进程
【4月更文挑战第28天】
5 0
|
1天前
|
Linux Shell 调度
【Linux】进程排队的理解&&进程状态的表述&&僵尸进程和孤儿进程的理解
【Linux】进程排队的理解&&进程状态的表述&&僵尸进程和孤儿进程的理解
|
1天前
|
监控 Unix Linux
深入理解Linux C/C++ 系统编程中系统调用导致的僵尸进程及其预防
深入理解Linux C/C++ 系统编程中系统调用导致的僵尸进程及其预防
45 0
|
1天前
|
Linux 调度
『 Linux 』僵尸进程与孤儿进程
『 Linux 』僵尸进程与孤儿进程
|
1天前
进程之 回收子进程之避免僵尸进程的产生
wait() 与 waitpid() 函数的使用.
30 0
|
1天前
|
监控 Unix Linux
Linux—进程状态、僵尸进程、孤独进程、优先级
Linux—进程状态、僵尸进程、孤独进程、优先级
46 0
|
1天前
|
存储 Linux Shell
Linux:进程等待 & 进程替换
Linux:进程等待 & 进程替换
30 9

相关实验场景

更多