【问题标题】:Scala system processes don't die after application deadScala系统进程在应用程序死后不会死
【发布时间】:2014-09-13 23:12:36
【问题描述】:

我在 Scala 中有一个对 ffmpeg 进行系统调用的应用程序。有时ffmpeg永远挂起。 我在 Mac OS X Eclipse 中运行这个应用程序。当我在 ffmpeg 命令运行时终止 java 应用程序时,ffmpeg 进程不会被终止。为什么?

import scala.sys.process.ProcessLogger
import scala.sys.process.stringSeqToProcess
import scala.sys.process.stringToProcess

object BugStreaming {
  def callFfmpeg(): (Int, String, String) = {
    val err = new StringBuilder
    val out = new StringBuilder

    val commandOutputs = ProcessLogger(
      (o: String) => out.append(o + "\n"),
      (e: String) => err.append(e + "\n"))

    println(s"ffmpeg saving...")

    val status = Seq("ffmpeg", "-i", "rtmp://200.136.27.12/live/tv", "-t", "5", "-y", "/tmp/x.wav") ! commandOutputs

    (status, out.toString, err.toString)
  }

  def main(args: Array[String]) {
    val (s, out, err) = callFfmpeg()
  }
}

【问题讨论】:

    标签: java scala jvm system-calls


    【解决方案1】:

    进程在单独的操作系统进程上运行。停止创建者进程(jvm)不会杀死子进程。
    还使用“!”运行该过程让调用者线程等待响应。
    如果您将调用“运行”函数而不是“!”它将返回允许停止的进程。

    val p = Seq("ffmpeg", "-i", "rtmp://200.136.27.12/live/tv", "-t", "5", "-y", "/tmp/x.wav").run(commandOutputs)
    val f = Future { p.exitValue }
    

    run 函数返回一个具有两个函数exitValue(): Intdestroy(): Unit 的进程。 exitValue 返回进程退出值(与“!”相同),为此它需要阻塞(这意味着调用线程等待进程完成)。 destroy 函数杀死进程。 你现在可以这样做:

    f.map{_ match {
      case 0 => //status ok
      case _ => //handling errors...
    }}
    

    如果你需要杀死它:

    p.destroy()
    

    【讨论】:

    • 杀死父亲时有没有办法杀死子进程?
    • @DanielCukier 这与操作系统有关,所以我不这么认为。但是您可以为此使用 jvm 关闭挂钩:sys.addShutdownHook{println("Bye Hook!"); p.destroy()} 这将在 jvm 关闭时终止进程。
    猜你喜欢
    • 2021-11-29
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    相关资源
    最近更新 更多