Ps
執行 ps 時是否存在競爭條件的風險?
我正在開始一個長時間執行的程序(在 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相當,則 PID將
ps
在掃描/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 欄位。