我是python的新手,使用多处理,我正在启动一个进程并通过此过程调用一个shell脚本。终止此进程后 shell 脚本继续在后台运行,我该如何杀死它,请帮忙。
蟒蛇脚本(test.py(
#!/usr/bin/python
import time
import os
import sys
import multiprocessing
# test process
def test_py_process():
os.system("./test.sh")
return
p=multiprocessing.Process(target=test_py_process)
p.start()
print 'STARTED:', p, p.is_alive()
time.sleep(10)
p.terminate()
print 'TERMINATED:', p, p.is_alive()
外壳脚本 (test.sh(
#!/bin/bash
for i in {1..100}
do
sleep 1
echo "Welcome $i times"
done
原因是由 os.system 调用生成的子进程生成了子进程本身。正如多处理文档中所解释的,该进程的后代进程不会被终止 - 它们只会成为孤立进程。所以。p.terminate()
会终止您创建的进程,但操作系统进程 (/bin/bash ./test.sh
( 只是分配给系统的调度程序进程并继续执行。
您可以使用子流程。取而代之的是:
import time
from subprocess import Popen
if __name__ == '__main__':
p = Popen("./test.sh")
print 'STARTED:', p, p.poll()
time.sleep(10)
p.kill()
print 'TERMINATED:', p, p.poll()
编辑:@Florian布鲁克打败了我。他首先回答了这个问题,这是值得称赞的。对于使用子进程的替代方法,仍然保留此答案,在 os.system(( 本身的文档中建议使用 os.system((。
os.system
在单独的进程中运行给定的命令。因此,您有三个过程:
- 运行脚本的主进程
- 运行
test_py_processes
的进程 - bash脚本运行的过程
进程 2 是进程 1 的子进程,进程 3 是进程 1 的子进程。
当您从进程 1 中调用Process.terminate
时,这会将SIGTERM
信号发送到进程 2。然后,该过程将终止。但是,SIGTERM
信号不会自动传播到进程 2 的子进程!这意味着当进程 2 退出时,进程 3 不会收到通知,因此会作为进程的子进程继续运行init
。
终止进程 3 的最佳方法取决于您的实际问题设置,请参阅此 SO 线程以获取一些建议。