如何终止进程(由 运行-process 创建)
How to kill process (created by run-process)
我想终止由 (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)
should send 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
执行后(除非main sbcl是killed/stopped,否则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-C
或 htop + kill
.
时,可以很好地终止脚本
因此如何在 sbcl 中实现 seamless/corpsless 杀戮?
使用时也会发生同样的情况:
(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))
解决方案如下所示(如果您使用与流程关联的流,则需要流程关闭):
(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))
或者正如 Sylvester 指出的那样,您可以省略 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.
This occurs for child processes, where the entry is still needed to allow the parent process to read its child's exit status.
一旦通过 process-exit-code
读取退出状态,进程就会被回收并将消失。
如果你使用的是便携式 uiop:run-program
而不是 sbcl 的,你可以通过第二次调用 运行-program 来终止 PID,给它 kill 命令,就像你一样会在 shell:
(uiop:run-program (format nil "kill ~a" (process-info-pid process)))
其中 process
是初始 run-program
的 return 结果,即启动您要终止的进程的结果。
我想终止由 (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)
should send 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
执行后(除非main sbcl是killed/stopped,否则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-C
或 htop + kill
.
因此如何在 sbcl 中实现 seamless/corpsless 杀戮?
使用时也会发生同样的情况:
(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))
解决方案如下所示(如果您使用与流程关联的流,则需要流程关闭):
(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))
或者正如 Sylvester 指出的那样,您可以省略 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.
This occurs for child processes, where the entry is still needed to allow the parent process to read its child's exit status.
一旦通过 process-exit-code
读取退出状态,进程就会被回收并将消失。
如果你使用的是便携式 uiop:run-program
而不是 sbcl 的,你可以通过第二次调用 运行-program 来终止 PID,给它 kill 命令,就像你一样会在 shell:
(uiop:run-program (format nil "kill ~a" (process-info-pid process)))
其中 process
是初始 run-program
的 return 结果,即启动您要终止的进程的结果。