我有一个Python代码如下:
import threading
import time
import subprocess, os, sys, psutil, signal
from signal import SIGKILL
def processing():
global p_2
global subp_2
.
.
.
if condition1: #loop again
threading.Timer(10,processing).start()
if condition2:
signal.signal(signal.SIGINT, signal_handler)
#signal.signal(signal.SIGTERM, signal_handler)
subp_2.terminate()
#os.kill(subp_2.pid, 0)
#subp_2.kill()
print " Status p_2: ", p_2.status
def signal_handler(signal, frame):
print('Exiting')
sys.exit(0)
def function():
global p_1
global subp_1
.
.
.
if condition1: #loop again
threading.Timer(5,function).start()
if condition2:
signal.signal(signal.SIGINT, signal_handler)
#signal.signal(signal.SIGTERM, signal_handler)
subp_1.terminate()
#os.kill(subp_1.pid, 0)
#subp_1.kill()
print " Status p_1: ", p_1.status
threading.Timer(10,processing).start()
subp_2 = subprocess.Popen('./myScript2.sh %s %s' % (arg0, arg1), shell=True)
p_2 = psutil.Process(subp_2.pid)
if __name__ == '__main__':
global p_1
global subp_1
.
.
.
subp_1 = subprocess.Popen(["/.../myScript1.sh"], shell=True)
p_1 = psutil.Process(subp_1.pid)
threading.Timer(5,function).start()
我无法终止进程 subp_1 和 subp_2。无论我尝试什么:.terminate()、.kill() 或 os.kill() 我仍然得到进程状态正在运行。谁能告诉我我错过了什么?任何提示表示赞赏。
最佳答案
当您使用shell=True
时,首先会生成一个运行shell的子进程。然后 shell 生成一个运行 myScript2.sh
的子进程。可以终止运行 shell 的子进程,而无需终止 myScript2.sh
子进程。
如果您可以避免使用shell=True
,那么这将是避免此问题的一种方法。如果使用用户输入来形成命令,绝对应该避免 shell=True
,因为它是 security risk .
在 Unix 上,默认情况下,由 subprocess.Popen
生成的子进程不是 session leader 。当您向 session 领导者发送信号时,该信号将传播到具有相同 session ID 的所有进程。因此,要让 shell 将 SIGTERM
传递给 myScript2.sh
,请使 shell 成为 session 领导者。
对于 Unix 上的 Python 版本<3.2,可以通过运行 shell 进程os.setsid()
来完成:
import os
subp_2 = subprocess.Popen('./myScript2.sh %s %s' % (arg0, arg1),
shell=True,
preexec_fn=os.setsid)
# To send SIGTERM to the process group:
os.killpg(subp_2.pid, signal.SIGTERM)
对于 Unix 上的 Python 版本 >= 3.2,将 start_new_session=True
传递给 Popen
。
对于 Windows,请参阅 J.F. Sebastian's solution .
关于python 无法使用 process.terminate 终止进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23228650/