我有一些类似的代码(未经测试):
import subprocess
import threading
t1 = threading.Thread(target=start_collect)
def start_collect():
process = subprocess.Popen("some command to collect data", stdout=subprocess.PIPE, stderr=subprocess.PIPE)
现在,我的主线程和t1线程都在某个时刻被杀死,而子进程仍在通过收集数据执行其命令。我希望它停止执行该命令并杀死子进程。因此,每当我的父线程(调用子进程的线程)被杀死时,我都想杀死子进程。有什么办法吗?
答案 0 :(得分:1)
因此Thread会一直执行到加入为止,因此我们必须很好地要求它以某种方式消失。如前所述,我可能会对其进行子类化,并创建一些方法,以一种干净的方式引用它可能产生的子流程并像这样优雅地终止它:
class InterruptibleThread(Thread):
def __init__(self, target):
super().__init__()
self.target = target
self.process = None
self._stopevent = Event()
self._periodicity = 1.0
def run(self):
self.process = Popen(self.target)
while not self._stopevent.is_set():
self._stopevent.wait(self._periodicity)
def stop(self):
self._stopevent.set()
self.process.terminate()
Thread.join(self)
我在Windows计算机上,因此以下序列会打开“命令提示符”窗口,并在产生的线程的stop()
方法被调用时终止:
>>> t = InterruptibleThread('cmd')
>>> t.target
'cmd'
>>> t.process # Returns None as it should
>>> t.start()
>>> t.process
<subprocess.Popen object at 0x00000295ACC704E0>
>>> t.process.poll() # Returns None as it should
>>> t.stop()
>>> t.process.poll()
1
>>>
现在,在您的程序中,您可能会有一些逻辑,要求您有t.join()
行,这很好,在这里,我只是通过使用t.stop()
来强制执行此操作,该行最终会连接线程,因此您调用t.join()
的程序可以通过覆盖join()
方法或程序中定义的t.stop()
的其他地方来工作。 t.process.poll()
检查进程是否已终止(此处仅出于演示目的而显示)。因此,现在您可以终止线程及其子进程。