Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Common lisp 无法使输入流在SBCL sb ext:运行程序中工作_Common Lisp_Inputstream_Sbcl_External Process - Fatal编程技术网

Common lisp 无法使输入流在SBCL sb ext:运行程序中工作

Common lisp 无法使输入流在SBCL sb ext:运行程序中工作,common-lisp,inputstream,sbcl,external-process,Common Lisp,Inputstream,Sbcl,External Process,而以下工作: (let* ((i (make-string-input-stream "foo bar baz")) (p (sb-ext:run-program "/bin/cat" '() :input i :output *trace-output* :wait t))) (sb-ext:process-close p)) 下面的代码没有-写入“001”后将停止: 所以它似乎在sbext:runprogram中默默地保留执行 这是Ubunt

而以下工作:

(let* ((i (make-string-input-stream "foo bar baz"))
       (p (sb-ext:run-program "/bin/cat" '() 
              :input i :output *trace-output* :wait t)))
  (sb-ext:process-close p))
下面的代码没有-写入“001”后将停止:

所以它似乎在
sbext:runprogram
中默默地保留执行

这是Ubuntu 16.04.1上的SBCL 1.3.6


有什么想法吗?弗兰克,提前谢谢你,正如我在评论中提到的,问题在于
:WAIT T
参数。它会导致对SB-EXT:RUN-PROGRAM的调用在子进程退出之前不会返回

在第一个示例中,您将字符串输入流传递给子进程
cat
将从流中读取输入,当输入结束时,将有文件结束,因此
cat
退出。在第二个示例中,程序没有可用的输入,因此它实际上是一个无限循环(就像在命令行上运行
cat
,不给它任何输入;它永远不会退出)

解决方案是使用
:WAIT NIL
。您还必须使用
close
关闭输入流,因为否则将没有EOF,并且
cat
将继续侦听更多输入。关闭流后,您还需要使用
SB-EXT:PROCESS-WAIT
来等待
cat
自动退出

(let* ((p (sb-ext:run-program "/bin/cat" '() 
                              :input :stream
                              :output *standard-output*
                              :wait nil))
       (s (sb-ext:process-input p)))
  (format s "foo bar baz~%")
  (finish-output s)
  (close s)
  (sb-ext:process-wait p)
  (sb-ext:process-close p))
我不确定您为什么对子输出使用
*TRACE-OUTPUT*
,因此我将其更改为
*STANDARD-OUTPUT*

另外,使用
格式
进行这样的调试有点难看。CommonLisp提供了实际的调试工具。在这种情况下,您可以使用:


这将使您进入调试器,显示下一步要计算的调用。您可以调用
STEP-NEXT
-restart继续下一个调用。

这就是工作原理,如下所示:


:WAIT T
表示等待进程退出。
:WAIT T
在两种情况下都存在,在工作情况下也存在,因此这不能作为解释。问题也不在于
sb:ext-run-program
正在离开它自己的执行,整个
let
blog没有运行显示任何日志输出-即使使用
:wait-nil
,也不会出现这种情况。无论如何,谢谢你,在第一种情况下,你给它一个字符串输入流
cat
读取输入,直到其EOFs,然后返回。在第二个示例中,您没有向流写入任何内容,因此不会出现EOF,并且
cat
将永远等待更多输入。好的-再次感谢。我明白你的观点,现在将集中讨论主要问题。这里我不明白的是:对于第二个例子,我确实为流程提供了输入,并且我完成了/刷新了输入流——这两个操作都是通过stream
s
完成的。我也感到困惑,因为Emacs/Slime没有阻止等待过程,所以REPL仍然是响应的。在SBCL REPL中进行测试时,等待过程实际上会阻塞。不管怎样,我按照你的建议尝试了
等待nil
,然后。。。成功了;)所以我仍然不能完全理解它,但我有一个解决方案——再次感谢。@FrankRuben Emacs/Slime使用不同的线程。REPL使用自己的线程,而其他任务则使用“工作”线程执行。使用slime list线程来列出它们。当您自己运行SBCL时,您只与单个线程进行交互。您可以使用sb-thread:make-thread启动另一个线程,结果将与您在Emacs中观察到的结果相似。
(let* ((p (sb-ext:run-program "/bin/cat" '() 
                              :input :stream
                              :output *standard-output*
                              :wait nil))
       (s (sb-ext:process-input p)))
  (format s "foo bar baz~%")
  (finish-output s)
  (close s)
  (sb-ext:process-wait p)
  (sb-ext:process-close p))
(step (let* ((p (sb-ext:run-program "/bin/cat" '() 
                                    :input :stream
                                    :output *standard-output*
                                    :wait nil))
             (s (sb-ext:process-input p)))
        (format s "foo bar baz~%")
        (finish-output s)
        (close s)
        (sb-ext:process-wait p)
        (sb-ext:process-close p)))
(let* ((p (sb-ext:run-program "/bin/cat" '() 
                              :input :stream 
                              :output *standard-output* 
                              :wait nil))
       (s (sb-ext:process-input p)))
  (format s "foo bar baz~%")
  (finish-output s)
  (sb-ext:process-wait p)
  (sb-ext:process-close p))