2015-06-11 6 views
1

Недавно я обнаружил, что проблема с запуском программы зависает sbcl 1.2.7 (32bits, linux). Код следующегоsbcl run-program зависает, когда есть большой объем вывода из программы

(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)) 

То есть, когда «кот test.out» производит много линий вывода на процесс-поток вывода объекта процесса, то `выполнения программы» вызова повесьте навсегда. На моей тестовой машине, когда число строк больше 900, эта проблема возникает. В противном случае просто отлично. Я сомневаюсь, что эта проблема вызвана каким-то блоком (возможно, буфер заполнен?), Когда выходные данные записываются в поток процесса-вывода. Если мы изменим код, следующий (во избежание данных, записанных в процесс-выходной поток), вызов выполнения программы возвращается немедленно:

(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.

+0

Как правило, вы получаете лучшую/быструю поддержку для этого из списка рассылки SBCL. –

ответ

1

Я также думаю, что это может быть проблема с буфером. Однако, если вы читаете: поток по строкам, это отлично работает:

(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))) 
+0

Да, это работает. Я думаю, что ключ добавляет «: wait nil» в run-program, тогда мы можем продолжать удалять данные и избегать заполнения буфера. Большое спасибо. – xiepan