僵尸可以有孤儿吗?收割僵尸会不会打扰孤儿?


27

据我了解,僵尸进程已经死亡,但仍作为进程表中的占位符存在,直到其父级(或者init如果僵尸本身是孤儿)检查其退出状态。

我对孤立进程的理解是,它们仍然是活动的并且正在运行,但是其父进程已经死亡。

由于僵尸已经死了,所以它的孩子将被视为孤儿,不是吗?他们会因为收割僵尸而受到影响吗?具体来说,是init仅在收割僵尸后才将其收为孩子,还是在父母成为僵尸后立即收养?


子进程在父进程init去世后立即重新加入父进程是有意义的(这包括使其成为僵尸)。僵尸不会照顾孩子。它什么也不会做。这只是一个pid现场漂浮的死亡状态信息。
PSkocik 2015年

这是否意味着僵尸的孤儿不能立即成为照顾者而成为僵尸init
2015年

正确。或者,如果它们确实变成了僵尸,那么直到init收割它们只有很小的时间。
PSkocik 2015年

6
我等不及这个问题的标题出现在“热网络问题”部分中了……
Nathan Osman 2015年

@NathanOsman,那真是太好了,但看起来好像不行。:(
通配符

Answers:


15

据我了解,僵尸进程已经死亡,但仍作为进程表中的占位符存在,直到其父级(如果僵尸本身是孤儿,则为init)检查其退出状态。

正确。

我对孤立进程的理解是,它们仍然是活动的并且正在运行,但是其父进程已经死亡。

正确。

由于僵尸已经死了,它的孩子将被视为孤儿,不是吗?

是。父母去世时,它已经死了。对于孩子来说,父母是否保持僵尸身份并不重要:孩子在父母去世时成为孤儿,然后他们与父母失去任何联系。

他们会因为收割僵尸而受到影响吗?具体来说,init将仅在收割僵尸后才将其收为孩子,还是在父母成为僵尸后立即收养它们?

不行,后者如上所述。


8

如果实验结果可以做到,那么看来至少systemdinit可以尽快收割僵尸的孤儿:

foo.c

#include <unistd.h>

int main(void)
{
    pid_t child = fork();
    if (child < 0)
        return -1;
    if (child == 0)
    {
        pid_t grand_child = fork();
        if (grand_child < 0)
            return -1;
        if (grand_child == 0)
            sleep (1000);
        else
            return 0;
    }
    else
        sleep (1000);
    return 0;
}

在一个终端中:

$ gcc -o foo foo.c
$ ./foo

在另一个终端:

$ pgrep foo                         
25548
25549
25550
$ pstree -pa 25548
foo,25548
  └─(foo,25549)
$ pstree -psa 25550
systemd,1
  └─foo,25550
$ ps -o stat,pid -p $(pgrep -d, foo)
STAT   PID
S+   25548
Z+   25549
S+   25550

好吧,这就是它的工作。
吉尔斯(Gillles)“所以-别再邪恶了”

@Gilles当然,收集孤儿是init的工作,但是是否有一些标准指定何时收集它?否则我会认为实现可能会有一些余地。
muru

我认为没有书面标准。POSIX仅声明“调用程序的所有现有子进程和僵尸进程的父进程ID应设置为实现定义的系统进程的进程ID。”,它没有说该系统进程是什么。应该做的,甚至是系统过程的通知方式。在Unix系统下,该系统进程为PID 1,它收到SIGCLD,并在它处理后立即获得进程。
吉尔斯(Gilles)“所以,别再邪恶了”

@Gilles的意思是某个地方可能存在一些(可能是运动恐怖症)初始化,它决定推迟收割僵尸的孩子直到僵尸消失?
muru 2015年

您可能还想提醒Gilles 记住unix.stackexchange.com/a/177361/5132。现在已经快四年了。☺
JdeBP
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.