Ps

執行 ps 時是否存在競爭條件的風險?

  • June 30, 2015

我正在開始一個長時間執行的程序(在 Java 中,在相關的情況下),然後想通過ps. 我基本上是這樣做的:

Process longRunningProcess = new ProcessBuilder(...).start();

Process psProcess = new ProcessBuilder("ps").start();
psProcess.waitFor();
// extract the PID from the output of psProcess

或者在 Bash 中等效地:

$ long_running_process > /dev/null & ps

ps問題是,長期執行的程序是否有可能處於某種尚未報告的仍在啟動狀態?或者是否有任何形式的保證,在ps執行時,長時間執行的程序將啟動到足以可見?重複執行該命令似乎總是包含該過程,但這顯然不能證明任何事情。

本文警告說,在啟動之後 啟動的命令可能存在競爭條件ps(例如ps | grep),但沒有提及任何關於在 之前啟動的程序ps

如果操作與 OpenJDK v6-b14相當,則 PIDps在掃描/proc虛擬文件系統時可用。你不能確定這個過程真的開始了(即做了什麼);你所知道的是一個 PID 已被保留和調度(想想看,程序可能已經死亡並處於殭屍狀態)。

但是,由於ps將您鎖定到 Unix 系統,您可以使用反射來探勘 ProcessBuilder 返回的對象,因為它會引導您進入 UnixProcess:

final class  [More ...] UNIXProcess extends Process {
   private FileDescriptor stdin_fd;
   private FileDescriptor stdout_fd;
   private FileDescriptor stderr_fd;
   private int pid; <----------------------------------------------
   private int exitcode;

當然,這一個 hack,但與產卵沒有太大區別ps——而且肯定更快。並不是真的有那麼大的風險——我看不到一個名為pid很快改變的 pid 欄位。

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