I am running on a linux machine a python script which creates a child process using subprocess.check_output() as it follows:
subprocess.check_output(["ls", "-l"], stderr=subprocess.STDOUT)
The problem is that even if the parent process dies, the child is still running. Is there any way I can kill the child process as well when the parent dies?
You can kill all child processes by first getting a list of all active child processes via the multiprocessing. active_children() function then calling either terminate() or kill() on each process instance.
Using the timeout Command. For killing a child process after a given timeout, we can use the timeout command. It runs the command passed to it and kills it with the SIGTERM signal after the given timeout. In case we want to send a different signal like SIGINT to the process, we can use the –signal flag.
A process can be killed by calling the Process. kill() function. The call will only terminate the target process, not child processes.
To close a single subprocess in Python, use the kill() method. The kill() is a built-in method used for terminating a single subprocess. The kill() command keeps running in the background.
Yes, you can achieve this by two methods. Both of them require you to use Popen
instead of check_output
. The first is a simpler method, using try..finally, as follows:
from contextlib import contextmanager @contextmanager def run_and_terminate_process(*args, **kwargs): try: p = subprocess.Popen(*args, **kwargs) yield p finally: p.terminate() # send sigterm, or ... p.kill() # send sigkill def main(): with run_and_terminate_process(args) as running_proc: # Your code here, such as running_proc.stdout.readline()
This will catch sigint (keyboard interrupt) and sigterm, but not sigkill (if you kill your script with -9).
The other method is a bit more complex, and uses ctypes' prctl PR_SET_PDEATHSIG. The system will send a signal to the child once the parent exits for any reason (even sigkill).
import signal import ctypes libc = ctypes.CDLL("libc.so.6") def set_pdeathsig(sig = signal.SIGTERM): def callable(): return libc.prctl(1, sig) return callable p = subprocess.Popen(args, preexec_fn = set_pdeathsig(signal.SIGTERM))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With