2

I have some code like this (not tested):

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) 

Now, my main thread and t1 thread both gets killed at some point while the subprocess is still executing its command by collecting data. I want it to stop executing that command and kill the subprocess. So, whenever my parent thread(the thread calling the subprocess) gets killed I want to kill the subprocess. Is there any way to do that?

1
  • You'd probably need to subclass Thread and assign the return of Popen as an attribute, that way when the subclass dies you can call some member function of it to terminate the process it spawned. Commented Dec 28, 2018 at 11:50

1 Answer 1

1

So a Thread will execute until it is joined, so we have to ask it nicely to go away somehow. As mentioned I would probably subclass it and create methods that allowed for a clean way of referencing the subprocess that it may have spawned and terminating it gracefully like so:

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) 

I am on a Windows machine, so the following sequence opens a Command Prompt window and terminates when the spawned thread has its stop() method called:

>>> 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 >>> 

Now in your program you'll likely have some logic that requires you to have a t.join() line, which is fine, here I just force it by using t.stop() which ultimate joins the thread so your programs call to t.join() will work by either overriding the join() method or somewhere else in your program calling the defined t.stop(). The t.process.poll() checks to see if the process was terminated (just shown here for demonstration purposes). So now you have a way of terminating a thread and its subprocesses.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.