孤儿进程与僵尸进程

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

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


孤儿进程

首先看一段示例代码:

#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 表示僵尸态)。僵尸进程的产生,往往是因为父进程没有对子进程的资源进行回收处理。因此为了避免这样的结果出现,程序需要在子进程选择退出时,由父进程进行资源的回收处理。

目录
相关文章
|
3月前
|
Linux C++
Linux c/c++进程之僵尸进程和守护进程
这篇文章介绍了Linux系统中僵尸进程和守护进程的概念、产生原因、解决方法以及如何创建守护进程。
35 0
|
8月前
|
Linux C语言
Linux: 僵尸进程究竟是什么?有什么危害?
Linux: 僵尸进程究竟是什么?有什么危害?
162 0
|
7月前
|
调度 Python
并发编程 , 孤儿进程 , 守护进程
并发编程 , 孤儿进程 , 守护进程
|
8月前
|
安全 Java
多线程(CAS, ABA问题, Runnable & Callable & 僵尸线程 & 孤儿进程)
多线程(CAS, ABA问题, Runnable & Callable & 僵尸线程 & 孤儿进程)
69 1
|
8月前
|
Linux Shell 调度
【linux进程(四)】僵尸进程和孤儿进程概念&进程优先级讲解
【linux进程(四)】僵尸进程和孤儿进程概念&进程优先级讲解
|
8月前
|
Linux 调度
【Linux】详解进程状态之僵尸进程——孤儿进程
【Linux】详解进程状态之僵尸进程——孤儿进程
141 0
|
8月前
|
NoSQL Linux Shell
【进程概念】进程状态以及僵尸进程(结合代码)
【进程概念】进程状态以及僵尸进程(结合代码)
|
8月前
|
弹性计算 Shell Linux
查找Linux 系统中的僵尸进程
【4月更文挑战第29天】
41 0
|
8月前
|
弹性计算 Shell Linux
查找 Linux 系统中的僵尸进程
【4月更文挑战第28天】
52 0
|
8月前
|
Linux Shell 调度
【Linux】进程排队的理解&&进程状态的表述&&僵尸进程和孤儿进程的理解
【Linux】进程排队的理解&&进程状态的表述&&僵尸进程和孤儿进程的理解
103 0