gpt4 book ai didi

java - 为什么 Java 进程在子进程仍处于打开状态时从 Gradle 挂起?

转载 作者:搜寻专家 更新时间:2023-10-30 19:46:48 25 4
gpt4 key购买 nike

如果在 java 中创建的进程创建了一个子进程,但随后返回,则 JVM 挂起,但没有进程 ID。

下面的示例应用程序(需要 Windows 和 Java 7)

import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.nio.file.Files;

public class SubProcessHang {

public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder builder = new ProcessBuilder("cmd", "/c", "start", "notepad.exe");
File output = Files.createTempFile("output", "txt").toFile();
builder.redirectError(Redirect.to(output));
builder.redirectOutput(Redirect.to(output));
Process process = builder.start();
process.waitFor();
int exitValue = process.exitValue();
System.out.println("Process exit value:: " + exitValue);
System.out.println("Output file length:: " + output.length());
System.exit(exitValue);
}
}

当应用程序运行时,它会创建三个进程:java --> 命令 --> 记事本cmd 立即返回并且 java 调用 System.exit(0),这会杀死 java 进程。但是记事本仍然存在,并且,当从 gradle(或 eclipse 就此而言)运行时,JVM 会一直挂起,直到该进程消失,而不返回它的返回值。

所以子进程还活着但是父进程已经被部分杀死,但是现在永远搁浅了。

用于重现此内容的 build.gradle 脚本

apply plugin: 'java'
apply plugin: 'application'
mainClassName = "SubProcessHang"

执行'gradle run'并得到这个输出:

C:\HangDemo>gradlew run
:compileJava
:processResources UP-TO-DATE
:classes
:run
Process exit value:: 0
Output file length:: 0
> Building 75% > :run

我知道这一定与 java 进程的创建方式有关,但我不知道该怎么做。

除了获取正在运行的 java 进程的 ID 并在关闭 Hook 中终止所有子进程之外,我还能做什么?

最佳答案

Process 的文档说

By default, the created subprocess does not have its own terminal or console. All its standard I/O (i.e. stdin, stdout, stderr) operations will be redirected to the parent process, where they can be accessed via the streams obtained using the methods getOutputStream(), getInputStream(), and getErrorStream(). The parent process uses these streams to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, or even deadlock.

http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html

也许您的进程正在创建 stdout 或 stderr 输出。尝试排空 InputStream 和 ErrorStream。

关于java - 为什么 Java 进程在子进程仍处于打开状态时从 Gradle 挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21918965/

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