如何杀死进程(由run-process创建)

时间:2015-02-28 18:38:54

标签: common-lisp sbcl

我想杀死由(sb-ext:run-program)启动的流程。

(let ((process (sb-ext:run-program "/path/to/process.sh" '() :wait nil)))
  (sleep 10)
  (sb-ext:process-close process)
  (sb-ext:process-kill process 9 :pid))

根据SBCL-Manual (sb-ext:process-kill process 9 :pid),应将SIGKILL (which has value 9)发送至process,从而消除此过程。

但是当我尝试使用虚拟过程时使用它:

#!/bin/bash

i=0
while [ $i -lt 4 ]
do
sleep 5
i+=1
done

它留下了一个后面甚至无法用htop + kill杀死的军团。

执行前的进程树如下所示:

|- /usr/bin/emacs
| |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl

执行期间:

|- /usr/bin/emacs
| |- /usr/local/bin/sbcl
| | |- /bin/bash /path/to/process.sh
| | | |- sleep 5
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl

执行后(除非主sbcl被终止/停止,否则process.sh不会终止):

|- /usr/bin/emacs
| |- /usr/local/bin/sbcl
| | |- process.sh
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl
| | |- /usr/local/bin/sbcl

手动启动并使用Ctr-Chtop + kill时,脚本可以被终止并终止。

因此,如何在sbcl中实现无缝/无人杀戮?

使用时会发生同样的情况:

(let ((process (sb-ext:run-program "/usr/local/bin/sbcl" '("--dynamic-space-size" "512" "--eval" "(sleep 100)") :wait nil)))
  (sleep 10)
  (sb-ext:process-close process)
  (sb-ext:process-kill process 9 :pid))

2 个答案:

答案 0 :(得分:4)

解决方案看起来像这样(如果您使用与您需要进程关闭的流程关联的流):

(let ((process (sb-ext:run-program "/home/user/processTest.sh" '() :wait nil)))
  (sleep 10)
  (sb-ext:process-kill process 15 :pid)
  (sb-ext:process-wait process)
  (sb-ext:process-close process)
  (sb-ext:process-exit-code process))   

或者正如西尔维斯特指出的那样,您可以省略process-close(如果您没有与该流程相关的任何流):

(let ((process (sb-ext:run-program "/home/user/processTest.sh" '() :wait nil)))
  (sleep 10)
  (sb-ext:process-kill process 15 :pid))                                

process-close会以一种zombie的方式影响该过程。

  

子进程会发生这种情况,其中仍然需要输入以允许父进程读取其子进程的退出状态。

一旦通过process-exit-code读取退出状态,该过程就会被收回并消失。

答案 1 :(得分:0)

如果您使用的是便携式uiop:run-program而不是sbcl的(uiop:run-program (format nil "kill ~a" (process-info-pid process))) ,则可以通过再次调用运行程序来杀死PID,就像在shell中一样,给其kill命令:< / p>

process

其中run-program是初始{{1}}的返回结果,而初始{{1}}是您要终止的进程的起始结果。