0

我需要创建一个调用应用程序(c++ 二进制文件)4000 次的脚本。该应用程序需要一些参数,并且每次调用都会将一个 zip 文件写入磁盘。因此,当脚本执行时,4000 个 zip 文件将被写入磁盘。该应用程序支持多线程。

我首先创建了一个完成这项工作的 bash 脚本,它运行良好。但现在我需要脚本独立于平台。因此,我尝试将脚本移植到 groovy,如下所示:

for (int i = 1; i <= 4000; i++) {
  def command = """myExecutable
                 a=$argA
                 b=$outDir"""

  def proc = command.execute()                 // Call *execute* on the string
  proc.waitFor()                               // Wait for the command to finish
  // Obtain status and output
  println "return code: ${ proc.exitValue()}"
  println "stderr: ${proc.err.text}"
  println "stdout: ${proc.in.text}" // *out* from the external program is *in* for groovy

  println "iteration : " + i

}

但是在将 381 个 zipfile 写入磁盘后,脚本就会挂起。每次通话或类似的事情后,我是否需要关闭该过程?

这里: http: //groovy.codehaus.org/Process+Management

它说它知道 java.lang.Process 可能会挂起或死锁。在 groovy 中做这样的事情是不行的吗?

我也会在 python 中尝试一下,看看它是否会出现同样的问题

4

2 回答 2

2

可能是输出流阻塞:

(1..<4000).each { i ->
    println "iteration : $i"

    def command = """myExecutable
                 a=$argA
                 b=$outDir"""

    def proc = command.execute()
    // Consume the outputs from the process and pipe them to our output streams
    proc.consumeProcessOutput( System.out, System.err )

    // Wait for the command to finish
    proc.waitFor()

    // Obtain status
    println "return code: ${proc.exitValue()}"
}
于 2013-11-15T09:01:46.220 回答
1

是的,您应该关闭属于流程的流。

或者,正如@tim_yates 所说,您应该使用consumeProcessOutput,或者,在并发解决方案中,waitForProcessOutput 会为您关闭它们。

对于并行计算,您可以使用 smth. 像这样:

import groovyx.gpars.GParsPool

GParsPool.withPool(8){ // Start in pool with 8 threads.
  (1..4000).toList().eachParallel {
    def p = "myExecutable a=$argA b=$outDir".execute()
    def sout = new StringBuffer();
    def serr = new StringBuffer();
    p.waitForProcessOutput(sout, serr)
    synchronized (System.out) {
      println "return code: ${ p.exitValue()}"
      println "stderr: $serr"
      println "stdout: $sout"
      println "iteration $it"
    }
  }
}
于 2013-11-14T22:49:24.180 回答