【问题标题】:External program blocks when run by Runtime exec由 Runtime exec 运行时的外部程序块
【发布时间】:2009-12-05 00:58:59
【问题描述】:

我正在尝试从 Java 应用程序中启动 VideoLAN 程序的实例。此处显示了我尝试执行此操作的一种方法:

Process p = Runtime.getRuntime().exec("\"C:\\Program Files\\VideoLAN\\VLC\\vlc.exe\" \"http://www.dr.dk/Forms/Published/PlaylistGen.aspx?qid=1316859&odp=true\" :sout=#std{access=udp,mux=ts,dst=127.0.0.1:63928}");

如果我执行上述命令,vlc 程序将被启动,并开始一个流式操作(它经过连接、缓冲和流式传输阶段)。

当命令由Runtime exec(或ProcessBuilder start)执行时,vlc程序会在到达缓冲阶段结束时挂起。如果 java 程序中的所有线程都终止/运行结束,vlc 程序将进入流式处理阶段。 java 进程在 vlc 进程关闭之前不会终止,因此这种行为显然是进程之间某种耦合的结果。

已尝试通过将命令写入 .cmd 文件然后执行它来间接执行该命令,但结果相同。

关于如何避免外部进程挂起的任何想法?

【问题讨论】:

  • 您希望让 Java 进程在 VLC 打开的情况下运行,还是让它终止并让 VLC 进程继续运行?我不确定是否真的发生了“耦合”,因为进程在自己的空间中运行,但也许有一些进程控制可以帮助你得到你想要的。

标签: java runtime external execute runtime.exec


【解决方案1】:

嗯,我的猜测是 VLC 填满了您的 STDOUT 缓冲区并挂在 printf 语句中,因为 STDOUT 正在等待该缓冲区清空。

您需要获取进程输出的流并读取它(即使您丢弃它)。

我建议你阅读这篇article

第 4 页是一个很好的例子,说明了如何在线程中读取流,这样您的子进程就不会阻塞。

【讨论】:

    【解决方案2】:

    这个网站太棒了:)。出于某种原因,一种我认为已经尝试过的方法突然开始起作用了。

    问题在于 vlc 写入其 stdErrOut(在提示符中执行时不可见)。一旦某个输出缓冲区已满,它就会阻塞。一种解决方案是将 stdErr 重定向到 stdOut,然后让线程清空进程对象的输入流。

    然而,这不是一个最佳解决方案,因为我需要大量的外部进程,而且你不能对它们的输入流进行非阻塞 I/O。将尝试让计时器服务驱动许多进程的空读取。非常欢迎其他有关如何解耦流程以避免此问题的建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-15
      • 1970-01-01
      • 1970-01-01
      • 2020-09-05
      • 1970-01-01
      • 1970-01-01
      • 2012-03-06
      • 1970-01-01
      相关资源
      最近更新 更多