开发者

Get subprocess id in Java

I'm creating subprocesses in this way:

Stri开发者_运维百科ng command = new String("some_program");

Process p = Runtime.getRuntime().exec(command);

How I can get that subprocess id?

P.S. I'm working on Linux.


There is still no public API for this (see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4244896) but there are workarounds.

A first workaround would be to use an external program like ps and to call it using Runtime.exec() to get the pid :)

Another one is based on the fact that the java.lang.Process class is abstract and that you actually get a concrete subclass depending on your platform. On Linux, you'll get a java.lang.UnixProcess which has a private field int pid. Using reflection, you can easily get the value of this field:

Field f = p.getClass().getDeclaredField("pid");
f.setAccessible(true);
System.out.println( f.get( p ) );


I tried (and failed) to do this a while back. I ended up wrapping my command in a shell script that dumped the pid to a file. Not the best solution but it got me past this hurdle.


Well there is no documented way to do this, but it happens that the Process implementation class is UNIXProcess, and it has a pid field. So you could use reflection to access this private field to get the ID. Googling around you will find other tricks of calling another shell to get ps output and that kind of thing. Nothing easy.


From here

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));
}


Given there is no public API to get the pid till now,

We can also apply the following trick obtain the pid:
IN CASE, YOU USE THE Liberica JDK, if not, you can check if you can use the same idea or not:

String pid = process.toString().substring(12, process.toString().indexOf(','));

The idea behind the above code, after checking the toString() impl inside ProcessImpl class.

@Override
public String toString() {
    return new StringBuilder("Process[pid=").append(pid)
            .append(", exitValue=").append(hasExited ? exitcode : "\"not exited\"")
            .append("]").toString();
}

Cons:

  • This way depend on impl!
  • When you change your JDK, you may change the parser to fetch the pid


Using Java 9, now you can fetch the pid directly as it is defined in the Process API interface.

process.pid();

The main code of the Process interface

/**
 * 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();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜