我是这样创建子进程的:
String command = new String("some_program");
Process p = Runtime.getRuntime().exec(command);
我该如何获取子进程的 id?
附:我正在 Linux 上工作。
ps
,并使用Runtime.exec()
调用它来获取pid :)java.lang.Process
类是抽象类的事实,实际上你会得到一个具体的子类,具体取决于你的平台。在Linux上,你会得到一个java.lang.UnixProcess
,它有一个私有字段int pid
。使用反射,你可以轻松地获取这个字段的值:Field f = p.getClass().getDeclaredField("pid");
f.setAccessible(true);
System.out.println( f.get( p ) );
UnixProcess
。 - Pascal Thivent从这里开始
public static void main(String[] args) throws IOException {
byte[] bo = new byte[100];
String[] cmd = {"bash", "-c", "echo $PPID"};
Process p = Runtime.getRuntime().exec(cmd);
p.getInputStream().read(bo);
System.out.println(new String(bo));
}
我之前尝试过这个(但失败了)。最终我将我的命令包装在一个 shell 脚本中,并将 pid 写入文件。虽然不是最好的解决方案,但它帮我克服了这个障碍。
其实没有官方文档提供的方法,但是进程实现类是UNIXProcess,它有一个pid属性。因此,你可以使用反射来访问这个私有属性来获取ID。在谷歌上搜索,你会找到其他调用另一个shell来获取ps输出的技巧。不过都不是很简单。
鉴于目前没有公共API可以获取pid
,
我们还可以采用以下技巧来获得pid
:
如果您使用Liberica JDK,否则,您可以检查是否可以使用相同的想法:
String pid = process.toString().substring(12, process.toString().indexOf(','));
ProcessImpl
类中的toString()
实现后。@Override
public String toString() {
return new StringBuilder("Process[pid=").append(pid)
.append(", exitValue=").append(hasExited ? exitcode : "\"not exited\"")
.append("]").toString();
}
缺点:
使用 Java 9
,现在您可以直接获取 pid,因为它在 Process API 接口中已经定义。
process.pid();
Process接口的主要代码
/**
* Returns the native process ID of the process.
* The native process ID is an identification number that the operating
* system assigns to the process.
*
* @implSpec
* The implementation of this method returns the process id as:
* {@link #toHandle toHandle().pid()}.
*
* @return the native process id of the process
* @throws UnsupportedOperationException if the Process implementation
* does not support this operation
* @since 9
*/
public long pid() {
return toHandle().pid();
}