参见英文答案 > How to terminate a python subprocess launched with shell=True 10个
我正在创建一个调用一些系统命令的Python应用程序.但是,如果它们花费太多时间(比如10s),我希望它终止这些命令.我尝试使用一些子过程自己做这件事 – 没有太大的成功.在stackoverflow上搜索后,我发现了以下问题:
Using module ‘subprocess’ with timeout
它有一个答案,几乎对我有用 – 问题是,当进程被“终止”时,它实际上不是 – 实际上,即使我的脚本完成后,该进程仍然在后台运行.当然这不是一个理想的效果,但我找不到解决方法.有没有一个解决这个问题的优先解决方案?
来自上述答案的代码(不良代码)供参考:
import subprocess, threading
class Command(object):
def __init__(self, cmd):
self.cmd = cmd
self.process = None
def run(self, timeout):
def target():
print 'Thread started'
self.process = subprocess.Popen(self.cmd, shell=True)
self.process.communicate()
print 'Thread finished'
thread = threading.Thread(target=target)
thread.start()
thread.join(timeout)
if thread.is_alive():
print 'Terminating process'
self.process.terminate()
thread.join()
print self.process.returncode
command = Command("echo 'Process started'; sleep 2; echo 'Process finished'")
command.run(timeout=3)
command.run(timeout=1)
解决方法:
你可以在这里找到答案:
只需将preexec_fn = os.setsid添加到Popen命令即可
终止使用:
os.killpg(self.process.pid, signal.SIGTERM)
代替:
self.process.terminate()
别忘了导入os,信号
所以你会得到:
import subprocess, threading
import os,signal
class Command(object):
def __init__(self, cmd):
self.cmd = cmd
self.process = None
def run(self, timeout):
def target():
print 'Thread started'
self.process = subprocess.Popen(self.cmd, shell=True, preexec_fn=os.setsid)
self.process.communicate()
print 'Thread finished'
thread = threading.Thread(target=target)
thread.start()
thread.join(timeout)
if thread.is_alive():
print 'Terminating process'
os.killpg(self.process.pid, signal.SIGTERM)
thread.join()
print self.process.returncode
command = Command("echo 'Process started'; sleep 2; echo 'Process finished'")
command.run(timeout=3)
command.run(timeout=1)
标签:python,multithreading
来源: https://codeday.me/bug/20190708/1402488.html