![WSL - 僵尸进程的不同行为](https://linux22.com/image/153768/WSL%20-%20%E5%83%B5%E5%B0%B8%E8%BF%9B%E7%A8%8B%E7%9A%84%E4%B8%8D%E5%90%8C%E8%A1%8C%E4%B8%BA.png)
我只是在 WSL 上玩弄僵尸进程。我写了一个非常简单的程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define CHILD 0
int main(){
int p;
p = fork();
if(p == CHILD){
printf("Kind-PID: %u\n", getpid());
exit(1);
} else if(p > CHILD){
sleep(30);
}
else return EXIT_FAILURE;
return EXIT_SUCCESS;
}
虽然我可以使用 来查看本机 Linux 上的僵尸进程ps
,但我在 WSL 上看不到僵尸进程。谁能解释为什么?
答案1
免责声明:我对 WSL 的内部运作一无所知。我对 Windows 进程生命周期细节的了解只是快速谷歌搜索的结果。请随时纠正我。
在 Linux 中,进程状态是使用其进程表条目以 Unix 风格跟踪的,进程表条目确定其 PID 号。因此,当进程死亡时,进程表条目无法被清除,直到(真实的或采用的)父进程读取死亡进程的退出代码 - 保持 PID 号被占用。表明进程已经死亡但尚未读取退出代码的进程表条目据说位于僵尸状态。系统中的所有进程都可以访问该状态和进程表中的各种其他信息位。
在 Windows 中,进程信息通过以下方式访问进程句柄。另外,正在运行的进程也有一个进程ID。当进程死亡时,PID号可以立即回收,因为退出代码将与死亡进程的句柄一起存储,与PID号分开管理。与 PID 号不同,进程句柄在其持有者将其关闭之前一直有效;它所引用的进程的死亡不会使进程句柄失效。
为了忠实地显示 WSL 中“僵尸”状态的等价物,WSLps
命令必须检查所有其他 WSL 进程的句柄以查找僵尸进程,然后以某种方式获取进程在以下情况下使用的 PID 号:它们是活动的 - 信息将不再存在,除非 WSL 子系统在进程活动时专门从 Windows 进程表中复制它。
但进程句柄不一定是公共信息:根据 WSL 的实现方式,WSL 进程可能只能看到其自己子进程的僵尸进程,只能看到属于同一用户的僵尸进程,或者可能是任何子进程的僵尸进程。仅 WSL 进程。为了重现 Unix 风格僵尸进程的外观,WSL 可能必须保留系统上每个 WSL 进程的句柄。
但从理论上讲,死掉的 WSL 进程的 Windows PID 可能会被回收到另一个活进程,而死掉的 WSL 进程的(真正的或采用的)父进程在读取死掉进程的退出代码之前会花一些时间。那么 WSL 应该报告什么作为僵尸的 PID?报告已被另一个活动进程使用的 PID 显然是错误的做法;报告僵尸的 PID 与它活着时实际的 PID 不同也是不正确的。
由于实际上您对僵尸进程无能为力,并且僵尸进程不会使 PID 数字空间变得混乱,因此 WSL 可能是一个有效的选择根本不尝试完全重现僵尸进程的概念对于像ps
.