使用带有超时的scala.sys.process

14 scala processbuilder

我觉得extreemly酷使用标准语法

import scala.sys.process._
    val countLogger = ProcessLogger(line => {println ("out line: " + line)},
                                 line => {println ("err line: " + line)})

    val exitCode = ("cat prog.c" #&& "gcc prog.c -o prog -lm" 
            #&& "echo running, this may hang" #&& "prog.exe") ! countLogger

    println("exitCode = " + exitCode)
Run Code Online (Sandbox Code Playgroud)

然而,最后一个进程会挂起.是否可以在超时时杀死它?

0__*_*0__ 23

您可以将进程包装在一个中Future(blocking(_)),如果在超时后没有返回,则调用process.destroy().

这就是我为我的小型处理器库所做的,例如,请参见此处.!您可以使用该run方法,而不是急于等待退出代码.以下是README的改编:

import scala.concurrent._
import ExecutionContext.Implicits.global
import scala.sys.process._

val p = "sleep 100".run()               // start asynchronously
val f = Future(blocking(p.exitValue())) // wrap in Future
val res = try {
  Await.result(f, duration.Duration(2, "sec"))
} catch {
  case _: TimeoutException => 
    println("TIMEOUT!")
    p.destroy()
    p.exitValue()
}
Run Code Online (Sandbox Code Playgroud)

  • 那么,期货的想法是让他们做异步做的事情.因此,"等待"有点违反直觉.但是如果你想要超时,那就是解决问题的方法,同时还能很好地应对未来.在实际场景中,你不会用`Await`来阻塞你的主线程,而是将它包装在`Future`中,这将是你在主逻辑中使用的实际未来结果.您可以重新抛出超时异常,而不是在超时情况下返回`exitValue`.例如,在我的处理器库中,调用`abort`将使用`Processor.Aborted`完成未来. (2认同)