Java中获取子进程id

发布于 2024-08-14 07:39:57 字数 184 浏览 2 评论 0原文

我以这种方式创建子流程:

String command = new String("some_program");

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

如何获取该子流程 ID?

PS我正在Linux上工作。

I'm creating subprocesses in this way:

String 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

我还不会笑 2024-08-21 07:39:57

目前仍然没有公共 API(请参阅 https://bugs.java.com/ bugdatabase/view_bug?bug_id=4244896),但有解决方法。

第一个解决方法是使用像 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 ) );

There is still no public API for this (see https://bugs.java.com/bugdatabase/view_bug?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 ) );
二智少女 2024-08-21 07:39:57

不久前我尝试过(但失败了)这样做。我最终将命令包装在 shell 脚本中,将 pid 转储到文件中。这不是最好的解决方案,但它让我克服了这个障碍。

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.

随遇而安 2024-08-21 07:39:57

好吧,没有记录的方法可以做到这一点,但碰巧 Process 实现类是 UNIXProcess,并且它有一个 pid 字段。所以你可以使用反射来访问这个私有字段来获取ID。谷歌搜索你会发现调用另一个 shell 来获取 ps 输出之类的其他技巧。没有什么是容易的。

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.

兔姬 2024-08-21 07:39:57

来自此处

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

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));
}
怎言笑 2024-08-21 07:39:57

鉴于目前还没有公共 API 来获取 pid

我们还可以应用以下技巧来获取 pid
如果您使用 Liberica JDK< /strong>,如果没有,您可以检查是否可以使用相同的想法:

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

上述代码背后的想法,在检查 ProcessImpl 内的 toString() impl 之后班级。

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

缺点:

  • 这种方式取决于 impl!
  • 当你改变你的JDK时,你可能会改变解析器来获取pid

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
许久 2024-08-21 07:39:57

使用 Java 9,现在您可以直接获取 Process API 接口中定义的 pid。

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

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文