如何在后代仍然存在时关闭 Windows 上的 Java 子进程 stdout 文件描述符
给定一个简单的批处理文件 c1.bat,包含:
start notepad 1> nul 2> nul
exit
和一个 Java 程序:
import java.io.InputStream;
public class ProcessTest {
public static void main(String[] args) throws Exception {
ProcessBuilder b = new ProcessBuilder();
b.command("c1.bat");
Process p = b.start();
new Thread(new ProcDrain(p)).start();
System.out.println("Parent process finished: " + p.waitFor());
}
private static class ProcDrain implements Runnable {
private final Process p;
private ProcDrain (Process p) {
this.p = p;
}
@Override
public void run() {
try {
InputStream in = p.getInputStream();
while (in.read() >= 0) { }
System.out.println("Inputstream drainer finished");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
第一个执行 c1.bat 的进程立即结束并生成另一个进程(记事本)。然而,drainer 线程在 read() 调用中被阻塞,并且在记事本关闭之前不会终止。这表明记事本保持打开原始进程的标准输出文件描述符,尽管批处理文件已重定向它。
批处理文件是否有某种方法可以关闭 stdout/stderr 文件描述符,以便一旦生成的进程实际退出,drainer 线程就不会在 read() 上阻塞?
Given a simple batch file, c1.bat, containing:
start notepad 1> nul 2> nul
exit
and a Java program:
import java.io.InputStream;
public class ProcessTest {
public static void main(String[] args) throws Exception {
ProcessBuilder b = new ProcessBuilder();
b.command("c1.bat");
Process p = b.start();
new Thread(new ProcDrain(p)).start();
System.out.println("Parent process finished: " + p.waitFor());
}
private static class ProcDrain implements Runnable {
private final Process p;
private ProcDrain (Process p) {
this.p = p;
}
@Override
public void run() {
try {
InputStream in = p.getInputStream();
while (in.read() >= 0) { }
System.out.println("Inputstream drainer finished");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
The first process, which executes c1.bat, ends promptly having spawned another process (notepad). The drainer thread however is blocked in the read() call, and does not terminate until notepad is closed. This suggests that notepad is holding open the stdout file descriptor of the original process, despite the batch file having redirected it.
Is there some way for the batch file to close the stdout/stderr file descriptors such that the drainer thread will not block on read() once the spawned process has actually exited?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论