Windows-Subsystem-for-Linux

WSL - 殭屍程序的不同行為

  • May 17, 2019

我只是在玩 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 上看不到殭屍程序。誰能解釋為什麼?

免責聲明:我對 WSL 的內部運作一無所知。我對 Windows 程序生命週期細節的了解只是快速Google搜尋的結果。隨時糾正我。

在 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 編號空間,因此對於 WSL來說,對於像這樣的命令*,完全不嘗試完全重現殭屍程序的概念*ps可能是一個有效的選擇.

引用自:https://unix.stackexchange.com/questions/519463