簡體   English   中英

Linux 僵屍進程未終止 Java ProcessBuilder

[英]Linux zombies processes left unterminated with Java ProcessBuilder

I have a java Spring REST API with a controller that runs a linux command with the ProcessBuilder class

. 該命令是生成的“查找”命令

問題是我在使用幾天后發現托管服務器中有很多未終止的進程。 我不知道為什么他們還在那里,沒有結束或被摧毀。 (我用 ps -ef 命令檢查過)

這是我的 runCmd function:


public static final BufferedReader runCmd(String cmd) throws IOException, InterruptedException {
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command("bash", "-c",  cmd);

        processBuilder.redirectErrorStream(true);
        Process process = processBuilder.start();

        BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));

        int ret = process.waitFor();
        return output;
}

有沒有辦法讓 sur 不再留下任何流程?

更新

問題僅來自具有非常大的命令 output stream (標准輸出) 感謝@DuncG 的提示

由於這個 output 很重要,我不能忽視它。 我必須找到一種消耗它的方法。

關於如何使用 Runnable Threads 的任何想法?

謝謝

您的命令是否生成大量 output? 僵屍的原因可能很簡單,cmd 寫了很多 output STDOUT 和 stream 在 BufferedReader 中阻塞。

您可以通過將重定向添加到 null 來測試這種情況 - 只需 append " > /dev/null" cmd 的末尾。 這將丟棄子進程 output 並意味着 BufferedReader 未充滿未讀數據/阻塞子進程。

processBuilder.command("bash", "-c",  cmd + " > /dev/null");

如果這解決了僵屍問題,您可以恢復重定向並使ProcessBuilder將 output 重定向到文件(在調用start()之前),或者您需要添加一個線程以在 IO 生成時使用它。

Path tmpdir = Path.of(System.getProperty("java.io.tmpdir"));
Path out = tmpdir.resolve("stdout.log");
processBuilder.redirectErrorStream(true);
processBuilder.redirectOutput(out.toFile());

最后,您應該返回輸出文件供調用者檢查,或者可以返回Files.newBufferedReader(out)

如果您不使用上述重定向到文件,這將使用線程將 output 存儲到 memory 緩沖區中。 請注意,如果不重定向 ERR->OUT,您也需要為 STDERR 復制:

Process p = pb.start();
ByteArrayOutputStream stdout = new ByteArrayOutputStream(8192);
new Thread(() -> copy(p.getInputStream(), stdout), "STDOUT").start();
int rc = p.waitFor();
byte[] sour = stdout.toByteArray()

使用方法:

private static void copy(InputStream in, OutputStream buf)
{
    try(var autoClose = in; var autoClose2 = buf)
    {
        in.transferTo(buf);
    }
    catch(IOException io)
    {
        throw new UncheckedIOException(io);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM