如果父级在 Java 中不使用 stdout/stderr,为什么进程会挂起? [英] Why does process hang if the parent does not consume stdout/stderr in Java?

查看:31
本文介绍了如果父级在 Java 中不使用 stdout/stderr,为什么进程会挂起?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如果你在 Java 中使用 ProcessBuilder.start 来启动一个外部进程,你必须使用它的 stdout/stderr(例如参见 此处).否则外部进程在启动时挂起.

I know that if you use ProcessBuilder.start in Java to start an external process you have to consume its stdout/stderr (e.g. see here). Otherwise the external process hangs on start.

我的问题是为什么它以这种方式工作.我的猜测是 JVM 将执行进程的 stdout/stderr 重定向到管道,如果管道没有空间,则写入管道会阻塞.有意义吗?

My question is why it works this way. My guess is that JVM redirects stdout/stderr of the executed process to pipes and if the pipes have no room the writes to the pipes block. Does it make sense?

现在我想知道为什么 Java 这样做.这种设计背后的原理是什么?

Now I wonder why Java does it way. What is the rationale behind this design?

推荐答案

Java 在这方面没有做任何事情.它只是使用操作系统服务来创建管道.

Java doesn't do anything in this area. It just uses OS services to create the pipes.

所有 Unix 类操作系统和 Windows 在这方面的行为都相同:在父子之间创建一个 4K 的管道.当管道已满时(因为一侧没有读取),写入过程会阻塞.

All Unix like OSs and Windows behave the same in this regard: A pipe with a 4K is created between parent and child. When that pipe is full (because one side isn't reading), the writing process blocks.

这是管道出现以来的标准.Java 无能为力.

This is the standard since the inception of pipes. There is not much Java can do.

您可能会争辩说,Java 中的流程 API 很笨拙,并且没有良好的默认设置,例如简单地将子流连接到与父流相同的 stdin/stdout,除非开发人员用特定的东西覆盖它们.

What you can argue is that the process API in Java is clumsy and doesn't have good defaults like simply connecting child streams to the same stdin/stdout as the parent unless the developer overrides them with something specific.

我认为当前 API 有两个原因.首先,Java 开发人员(即 Sun/Oracle 的人员)确切地知道进程 API 是如何工作的以及您需要做什么.他们非常了解,以至于他们没有想到 API 可能会令人困惑.

I think there are two reasons for the current API. First of all, the Java developers (i.e. the guys at Sun/Oracle) know exactly how the process API works and what you need to do. They know so much that it didn't occur to them that the API could be confusing.

第二个原因是没有适合大多数人的好的默认设置.你不能真正连接父母和孩子的标准输入;如果您在控制台上输入内容,输入应该转到哪个进程?

The second reason is that there is no good default that will work for the majority. You can't really connect stdin of the parent and the child; if you type something on the console, to which process should the input go?

同样,如果你连接 stdout,输出也会去某个地方.如果您有一个 Web 应用程序,则可能没有控制台,或者输出可能会出现在没人会想到的地方.

Similarly, if you connect stdout, the output will go somewhere. If you have a web app, there might be no console or the output might go somewhere where no one will expect it.

当管道已满时,您甚至不能抛出异常,因为在正常操作期间也会发生这种情况.

You can't even throw an exception when the pipe is full since that can happen during the normal operation as well.

这篇关于如果父级在 Java 中不使用 stdout/stderr,为什么进程会挂起?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆