新しい "ProcessHandle
" APIをJava 9で単純な "Dockerized" Javaプログラムで試してみましたが、プロセスIDを取得する際の動作の違い実行中のプロセスの具体的には、メソッドProcessHandle.pid()
を呼び出すとき、Dockerの結果のPIDはホストに表示されるネイティブIDとは異なりますが、ドキュメントの "プロセスのネイティブプロセスIDを返す"と言います。さらに、ProcessHandle.allProcesses()
の結果には違いがありました。実証するためにDockerのJava 9 ProcessHandle API:PID値と可視プロセスの違い
、以下のプログラムは、以下のん:
- は、現在のプロセスのPIDを印刷し、
- は(その情報を印刷する時間を与えるために)数秒間眠る子プロセスを生成します、
- 最後に、すべての可視プロセスを印刷します。
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(""));
}
(ドッカーせず)は、通常のアプリケーションを実行すると、期待どおり、出力されます。現在のプロセスのネイティブ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
私はドッカー(ドッカーがboot2dockerのLinux上で実行されているとのWindows 7)で実行した場合、プロセスのはるかに小さいサブセットが表示されている、とPIDは、ホスト上のものと一致していません。
しかしながら、結果として得られるプログラムの出力は以下の代わりに、PIDが1と16を示しています。
$ docker run test/java9-processhandle-example:1.0
上記のコマンドを実行した後、ホストは、次のプロセスを示しています見えるプロセスには、コンテナプロセスと生成されたプロセスが含まれます。
これが期待されているのでしょうか。私は比較的新しいDockerだから、もしこれがコンテナによって引き起こされた制限だとすれば、誰かがそれを説明できるならばうれしいだろう(LinuxやWindowsのDockerのような別のDockerの設定で再現可能かどうかもわからないサーバ)。さもなければ、これはコンテナに適用されたときのAPI自体の制限です(これはJavadocには記載されていないようです)。
### 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
私はこれをほとんど期待しています。コンテナは、ホストのPIDシーケンスの知識を持っていてはなりません。 – Makoto
[ドッカーとホストの間のPIDマッピング](https://stackoverflow.com/questions/33328841/pid-mapping-between-docker-and-host)の可能な複製。これはJavaまたはそのバージョンIMO。 VonCのリンクをたどって詳細を理解することができます。 – nullpointer
ここに移動し、さらに明確にするために、DockerでProcessHandlerを使用する方法(コンテンツでは疑わしい)や、ドッカーとホストで異なるPIDを取得する方法があります。 – nullpointer