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

查看:96
本文介绍了如果父进程不在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在这方面没有做任何事情。它只是使用OS服务来创建管道。

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

所有类似操作系统和Windows的Unix在这方面表现相同:在父和子之间创建一个带有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,输出将会在某处。如果你有一个网络应用程序,可能没有控制台或输出可能会在没有人期望的地方。

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天全站免登陆