Common lisp 当程序有大量输出时,sbcl运行程序挂起

Common lisp 当程序有大量输出时,sbcl运行程序挂起,common-lisp,freeze,sbcl,Common Lisp,Freeze,Sbcl,最近我发现sbcl 1.2.7(32位,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"

最近我发现sbcl 1.2.7(32位,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时,就会发生此问题。否则就好了。我怀疑在将输出数据写入进程输出流时,由于某种阻塞(可能缓冲区已满?)而导致的此问题。如果我们按以下方式更改代码(避免将数据写入流程输出流),则运行程序调用将立即返回:

(length 
  (with-output-to-string (s)
      (run-program "/bin/bash" (list "-c" "cat test.out")
                   :output s)))
;;=> 69300
我不知道那是不是一只虫子。当挂起问题发生时,是否有方法使调用返回


还有一个类似的问题:,但我不知道为什么运行程序调用挂起在那里。

我还认为可能是缓冲区问题。但是,如果您逐行读取from: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)))

通常,您可以从SBCL邮件列表中获得更好/更快的支持。是的,这很有效。我认为关键是添加“:wait nil”来运行程序,然后我们可以继续删除数据并避免缓冲区被填满。谢谢。