【问题标题】:sbcl run-program hang when there is large amount of output from program当程序有大量输出时,sbcl run-program 挂起
【发布时间】:2015-06-11 09:12:06
【问题描述】:

最近我发现 sbcl 1.2.7 (32bits, linux) 的运行程序挂起问题。代码如下

(progn
  (with-open-file (s "test.out" :direction :output :if-exists :supersede)
    (loop repeat 900 do (write-line (make-string 76 :initial-element #\x) s)))
  (run-program "/bin/bash" (list "-c" "cat test.out") :output :stream))

当“cat test.out”产生多行输出到进程对象的进程输出流时,`run-program'调用永远挂起。在我的测试机上,当行数大于 900 时,就会出现这个问题。否则就好了。当输出数据写入进程输出流时,我怀疑这个问题是由某种块(可能缓冲区已满?)引起的。如果我们将代码更改如下(避免将数据写入流程输出流),run-program 调用会立即返回:

(length 
  (with-output-to-string (s)
      (run-program "/bin/bash" (list "-c" "cat test.out")
                   :output s)))
;;=> 69300

我不知道这是否是一个错误。当挂起问题发生时,是否有方法可以让调用返回?

还有一个类似的问题:how-to-read-from-large-process-output-correctly,但我不明白为什么 run-program 调用挂在那里。

【问题讨论】:

  • 通常您可以从 SBCL 邮件列表中获得更好/更快的支持。

标签: common-lisp freeze sbcl


【解决方案1】:

我也认为这可能是一些缓冲问题。但是,如果您逐行阅读 :stream ,则效果很好:

(let ((process
       (run-program "/bin/bash" (list "-c" "cat test.out") :output :stream :wait nil)))
  (loop for line = (read-line (process-output process) nil :eof)
        until (eq line :eof)
        do (print line)))

【讨论】:

  • 是的,这行得通。我认为关键是在运行程序中添加“:wait nil”,然后我们可以继续删除数据并避免缓冲区满。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2011-07-27
  • 1970-01-01
  • 2015-10-16
  • 2015-02-06
  • 1970-01-01
  • 2019-06-02
  • 2021-12-07
  • 1970-01-01
相关资源
最近更新 更多