How to close Subprocess that runs other Subprocess on Windows?

Issue

I am facing the following problem and can’t solve it.

  1. A runs B as multiprocessing.Process()
  2. B runs C as subprocess.run()
  3. A terminates B by multiprocessing.Process.terminate()
  4. Expected: B and C are terminated
    Result: B is terminated and C runs in background

Important additional information

  • A, B, C are programs
  • A is my program that I develop
  • B, C are external programs not developed by me and I have no control
    of
  • Solution must work on Windows

Question Does anyone have any solution or know if it isn’t possible?

Following code describes my problem on example:

# main.py - Process A
# Runs Process B
import multiprocessing
from Manager import manager
from time import sleep

def main():
    proc = multiprocessing.Process(target=manager)

    proc.start()
    print("[MAIN] Process going sleep")
    sleep(3)
    print("[MAIN] Process is awake now. Beginning to terminate")
    proc.terminate()
    proc.join()
    print("[MAIN] Process Manager terminated.")

if __name__ == "__main__":
    main()
# Manager.py - Process B
# Cannot change any code
# Runs process C
import subprocess

def manager():
    print("[MANAGER] START")
    subprocess.run(["python", "sleepery.py"])
    print("[MANAGER] Terminated")
# sleepery.py - Process C
# Cannot change any code
from time import sleep

def sleeper():
    """This process prints info every two seconds for 8"""
    for _ in range(4):
        sleep(2)
        print(f"[SLEEPER] prints!")
    print("[SLEEPER] ends")

if __name__ == "__main__":
    sleeper()

OUTPUT

[MAIN] Process going sleep
[MANAGER] START
[SLEEPER] prints!
[MAIN] Process is awake now. Beginning to terminate
[MAIN] Process Manager terminated.
[SLEEPER] prints! 
[SLEEPER] prints!
[SLEEPER] prints!
[SLEEPER] ends

WANTED OUTPUT

[MAIN] Process going sleep
[MANAGER] START
[SLEEPER] prints!
[MAIN] Process is awake now. Beginning to terminate
[MAIN] Process Manager terminated.

My research
The only thing that works is to kill all python processes by taskkill
But it isn’t exactly graceful

Solution

Use a Job object, this allows you to group all child processes in this job and kill them all in a single step.

Answered By – Anders

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published