想要在python中杀死线程时终止子进程

时间:2018-12-28 11:41:25

标签: python multithreading python-2.7 subprocess

我有一些类似的代码(未经测试):

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线程都在某个时刻被杀死,而子进程仍在通过收集数据执行其命令。我希望它停止执行该命令并杀死子进程。因此,每当我的父线程(调用子进程的线程)被杀死时,我都想杀死子进程。有什么办法吗?

1 个答案:

答案 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()检查进程是否已终止(此处仅出于演示目的而显示)。因此,现在您可以终止线程及其子进程。