gpt4 book ai didi

Docker : Difference in PID values and visible processes 中的 Java 9 ProcessHandle API

转载 作者:行者123 更新时间:2023-12-03 18:42:19 27 4
gpt4 key购买 nike

在尝试新的 ProcessHandle 时Java 9 中的 API 在一个简单的“Dockerized”Java 程序上,我发现在检索正在运行的进程的进程 ID 时的行为有所不同。具体调用方法时 ProcessHandle.pid()Docker 上生成的 PID 与主机上显示的 native ID 不同,尽管文档说该方法“返回进程的 native 进程 ID”。此外,ProcessHandle.allProcesses() 的结果也存在差异。

为了演示,下面的程序执行以下操作:

  1. 打印当前进程的PID,
  2. 生成一个 sleep 几秒钟的子进程(以便有时间打印其信息),
  3. 最后打印出所有可见的进程。

public static void main(String[] args) {
System.out.println("### Current process info ###");
ProcessHandle currentProcess = ProcessHandle.current();
printInfo(currentProcess);

System.out.println();

// Fork a child process that lasts for a few seconds
spawnProcess("jshell --startup ./sleep.txt");

printAllVisibleProcesses();
}

private static void printAllVisibleProcesses() {
System.out.println("### Visible processes info ###");
ProcessHandle.allProcesses().forEach(ProcessHandleExamples::printInfo);
System.out.println();
}

private static void spawnProcess(String command) {
System.out.println("Spawning: " + command);
try {
Runtime.getRuntime().exec(command);
} catch (IOException e) {
e.printStackTrace();
}
}

private static void printInfo(ProcessHandle processHandle) {
ProcessHandle.Info processInfo = processHandle.info();
System.out.println("Process ID: " + processHandle.pid());

System.out.println("Process arguments: " + Arrays.toString(processInfo.arguments().orElse(new String[0])));
System.out.println("Process executable: " + processInfo.command().orElse(""));
System.out.println("Process command line: " + processInfo.commandLine().orElse(""));
System.out.println("Process start time: " + processInfo.startInstant().orElse(null));
System.out.println("Process total cputime accumulated: " + processInfo.totalCpuDuration().orElse(null));
System.out.println("Process user: " + processInfo.user().orElse(""));
}

正常运行应用程序时(没有Docker),输出符合预期;它包括当前进程、其子进程和许多其他可见进程的 native PID。

### Current process info ###
Process ID: 7756
Process arguments: []
Process executable: D:\Dev\Java\jdk-9\bin\java.exe
Process command line:
Process start time: 2017-10-08T12:23:46.474Z
Process total cputime accumulated: PT0.4368028S
Process user: manouti

Spawning: jshell --startup ./sleep.txt
### Visible processes info ###
... skipping some output
Process ID: 8060
Process arguments: []
Process executable: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
Process command line:
Process start time: 2017-10-08T12:20:04.758Z
Process total cputime accumulated: PT10.4676671S
Process user: manouti

Process ID: 7756
Process arguments: []
Process executable: D:\Dev\Java\jdk-9\bin\java.exe
Process command line:
Process start time: 2017-10-08T12:23:46.474Z
Process total cputime accumulated: PT0.8268053S
Process user: manouti

Process ID: 8080
Process arguments: []
Process executable: D:\Dev\Java\jdk-9\bin\jshell.exe
Process command line:
Process start time: 2017-10-08T12:23:46.992Z
Process total cputime accumulated: PT0.0780005S
Process user: manouti

当我在 Docker 上运行时(Windows 7,Docker 在 boot2docker Linux 上运行),可见的进程子集要小得多,而且 PID 与主机上的进程不匹配。 p>

$ docker run test/java9-processhandle-example:1.0

运行上述命令后,宿主机显示如下过程:

enter image description here

但是,下面生成的程序输出显示 PID 1 和 16,而不是 4291 和 4333。可见进程包括容器进程和派生进程。

我想知道这是否符合预期。由于我对 Docker 比较陌生,如果这是由容器引起的限制,我会很高兴有人能解释它(我也不确定这是否可以在不同的 Docker 设置上重现,例如 Linux 或 Windows 上的 Docker服务器)。否则,在容器中应用时,这是 API 本身的限制吗(Javadocs 中似乎没有提到)?

### Current process info ###
Process ID: 1
Process arguments: [ProcessHandleExamples]
Process executable: /usr/lib/jvm/java-9-openjdk-amd64/bin/java
Process command line: /usr/lib/jvm/java-9-openjdk-amd64/bin/java ProcessHandleExamples
Process start time: 2017-10-08T14:17:48.420Z
Process total cputime accumulated: PT0.35S
Process user: root

Spawning: jshell --startup ./sleep.txt
### Visible processes info ###
Process ID: 1
Process arguments: [ProcessHandleExamples]
Process executable: /usr/lib/jvm/java-9-openjdk-amd64/bin/java
Process command line: /usr/lib/jvm/java-9-openjdk-amd64/bin/java ProcessHandleExamples
Process start time: 2017-10-08T14:17:48.420Z
Process total cputime accumulated: PT0.6S
Process user: root

Process ID: 16
Process arguments: [--startup, ./sleep.txt]
Process executable: /usr/lib/jvm/java-9-openjdk-amd64/bin/jshell
Process command line: /usr/lib/jvm/java-9-openjdk-amd64/bin/jshell --startup ./sleep.txt
Process start time: 2017-10-08T14:17:49.070Z
Process total cputime accumulated: PT0.03S
Process user: root

最佳答案

这不是 Java 或 Java 9 特有的,它是一个 docker 主题。

每个容器都有自己的 PID 命名空间,容器中运行的第一个进程的 PID 为 1。

您可以在 docker documentation 中阅读更多相关信息,特别是:

By default, all containers have the PID namespace enabled.

PID namespace provides separation of processes. The PID Namespace removes the view of the system processes, and allows process ids to be reused including pid 1.

关于Docker : Difference in PID values and visible processes 中的 Java 9 ProcessHandle API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46632572/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com