首页WIN7问题ub激巴约火土untu Linux怎么解决僵尸进程?

ub激巴约火土untu Linux怎么解决僵尸进程?

时间2022-11-26 13:45:22发布分享专员分类WIN7问题浏览94

Linux 允许进程查询内核以获得其父进程的 PID,或者其任何子进程的执行状态wifexited 。例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如 wait() 这样的一些库函数检查子进程是否终止。如果子进程七调销概同已经终止,那么,它的终止代号将告诉父进程这个任务是否已成功地完成。

为了遵循这些设计原则,不允许 Linux 内核在进程一终止后就丢弃包含在进程描述符字段中的数据wifexited 。只有父进程发出了与被终止的进程相关的 wait() 类系统调用之后,才允许这样做。这就是引入僵死状态的原因:尽管从技术上来说进程已死,但必须保存它的描述符,直到钱酒居责父进程得到通知。

如果一个进程已经终止,但是它的父进程尚未调用 wait() 或 waitpid() 对它进行清理,这时的进程状态称为僵死状态,处于僵死状态的进程称为僵尸进程(zombie process杂严谁过与)wifexited 。任何进程在刚来自终止时都是僵尸进程,正常情况下,僵尸进程都立刻被父进程清理了。

僵尸进程是如何产生的

 在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他,那审乎额么他将变成一个僵尸进程wifexited 。通过ps命令360问答查看其带有defunct聚加远医于的标志。僵尸进程是一个吸木者曾早已死亡的进程,但在进程表 (processs table)中仍占了一个位置(slot)。

但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程wifexited 。因为每个进程结束的时候,系统赵片转领都会扫描当前系统中所运行的所有进程,看看有没有哪个 进程是刚刚结束的这个怕破责老站觉态乎控进程的子进程,如果是的话,就由Init进程来接管他,成为他的父进程,从而保证每个进程都会有训买十须由四一个父进程。而Init进程会自动 wait其子进程,因此被Init接管的所有进程都不会变成僵尸进程。

抓开为了观察到僵尸进程wifexited ,我们自己条印云微合持直京下写一个不正常的程序,父进程 fork 出子进程,子进程终止,而父进程既不终止也不调用 wait 清理子进程:

1

wifexited 你知凯你效影龙元2

3

4

5

6

7

8

9

10

1英组极它节第所迅氢吸1

12

13

14

15

矿磁底织还把16

17

18

19

20

21

22

23

24

25

26

27

#船冷include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

int main(void)

卫助夫品民府策{

  int i = 100;

  pid_t pid=fork();

  if(pid < 0)

    perror("fork failed.");

    exit(1);

  if(pid > 0)

    printf("This is the parent process. My PID is %d.\n", getpid());

    for(; i > 0; i--)

      sleep(1);

  else if(pid == 0)

    printf("This is the child process. My PID is: %d. My PPID is: %d.\n", getpid(), getppid());

  return 0;

把上面的代码保存到文件 zomprocdemo.c 文件中wifexited ,并执行下面的命令编译:

1

$ gcc zomprocdemo.c -o zomprocdemo

然后运行编译出来的 zomprocdemo 程序:

1

$ ./zomprocdemo

ub激巴约火土untu Linux怎么解决僵尸进程?

请点击输入图片描述

此时子进程已经退出,但是父进程没有退出也没有通过 wait() 调用处理子进程wifexited 。我们使用 ps 命令查看进程的状态:

ub激巴约火土untu Linux怎么解决僵尸进程?

请点击输入图片描述

上图红框中的大写字母 "Z" 说明 PID 为 112712 的进程此时处于僵死的状态wifexited 。

让我们接着往下看!在结束 sleep 后父进程退出wifexited 。当父进程退出后,子进程会变成孤儿进程,此时它会被一个管理进程收养。在不同的系统中,这个管理进程不太一样,早期一般是 init 进程,Ubuntu 上是 upstart,还有近来的 Systemd。但是它们都完成相同的任务,就是 wiat() 这些孤儿进程,并最终释放它们占用的系统进程表中的资源。这样,这些已经僵死的孤儿进程就彻底的被清除了。

僵尸进程的危害

在进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等wifexited 。但是仍然为其保留一定的信息(包括进程号 PID,退出状态 the termination status of the process,运行时间 the amount of CPU time taken by the process 等)。直到父进程通过 wait / waitpid 来取时才释放。

如果进程不调用 wait / waitpid 的话, 那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程wifexited 。

如何处理僵尸进程

僵尸进程的产生是因为父进程没有 wait() 子进程wifexited 。所以如果我们自己写程序的话一定要在父进程中通过 wait() 来避免僵尸进程的产生。

当系统中出现了僵尸进程时,我们是无法通过 kill 命令把它清除掉的wifexited 。但是我们可以杀死它的父进程,让它变成孤儿进程,并进一步被系统中管理孤儿进程的进程收养并清理。

下面的 demo 中wifexited ,父进程通过 wait() 等待子进程结束:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

#include <sys/types.h>

#include <sys/wait.h>

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

int main(void)

  pid_t pid;

  pid = fork();

  if (pid < 0)

    perror("fork failed");

    exit(1);

  if (pid == 0) {

    int i;

     for (i = 3; i > 0; i--)

      printf("This is the child\n");

      sleep(1);

     // exit with code 3 for test.

    exit(3);

  else

    int stat_val;

    wait(&stat_val);

     if (WIFEXITED(stat_val))

       printf("Child exited with code %d\n", WEXITSTATUS(stat_val));

  return 0;

demo 中父进程不仅等待子进程结束,还通过 WEXITSTATUS 宏取到了子进程的 exit codewifexited 。

爱资源吧版权声明:以上文中内容来自网络,如有侵权请联系删除,谢谢。

Linux解决僵程?untuLinuxuntuwifexited
wifexited 在哪个头文件中 IE退役后,国产浏览器要用内容聚合称王