收割孩子意味着什么?

npp*_*npp 2 c zombie-process waitpid

我刚刚听了一个演讲,总结为:

收割

  • 由父级对终止的子级执行(使用 wait 或 waitpid)

    父母获得退出状态信息

    内核然后删除僵尸子进程

所以我明白收割是通过调用waitwaitpid从父进程完成的,之后内核删除僵尸进程。如果确实是这种情况,那么只有在调用waitor时才会进行收割waitpid,为什么在 theor 入口函数中返回后子进程实际上消失了 - 我的意思是确实看起来好像子进程已经被收割了,因此没有资源即使父进程可能没有等待,也浪费了。

所以唯一可能的“收获”打电话时wait还是waitpid?只要进程从其入口函数返回并退出(我假设所有进程都这样做),进程是否会被“收割” - 谈论“收割”好像它是特殊的东西有什么意义?

jxh*_*jxh 9

调用的目的wait*()是允许子进程向父进程报告状态。当子进程退出时,操作系统将状态数据保存在一个小数据结构中,直到父进程读取它。从这个意义上说,收获就是清理那个小数据结构。

如果父级不关心等待子级的状态,则可以以允许父级忽略状态的方式编写代码,因此收获是半自动发生的。一种方法是忽略该SIGCHLD信号。

另一种方法是执行双分叉来创建孙进程。执行此操作时,“父级”在wait()调用fork(). 然后,子进程执行另一次fork()创建孙子进程,然后立即退出,导致父进程解除阻塞。现在,孙子完成了真正的工作,并通过该init过程自动收获。


Ste*_*mit 6

子进程退出时并没有完全“消失”。它不再作为正在运行的进程存在,并且它的大部分/所有资源(内存、打开的文件等)都被释放,它仍然保留在进程表中。它保留在进程表中,因为这是存储其退出状态的位置,以便父进程可以通过调用其中一个wait变体来检索它。如果父wait进程调用失败,进程表条目会一直存在——这就是让它成为“僵尸”的原因。

我说它的大部分/所有资源都被释放了,但肯定仍在消耗的一种资源是进程表槽。

只要(死)子wait进程的父进程存在,内核就不知道父进程最终不会调用,所以进程表槽必须留在那里,以便最终调用wait(如果有的话)可以返回正确的退出状态。

如果父wait进程最终退出(从未调用),子进程将被祖父进程继承,这通常是像 shell 一样的“主”进程,或者init,它会定期调用wait并最终“收割”可怜的年轻僵尸。

所以,是的,正如您的讲座所说,父母正确“收获”孩子的唯一方法是调用其中一个wait功能。(或者退出,但如果父级长期运行,那就很糟糕了。)