SunAwtCanvas
SunAwtCanvas

Reputation: 1460

How to Terminate Multiprocessing Parent Process?

How can I get my Child process to terminate the Parent process?

I was thinking something along the lines of...

Child gets Parent Process's PID and terminates the parent using psutil

Here's my code

from multiprocessing import Process, Value
import keyboard
import sys

def KeyboardScan(v):
    Paused = False
    while True:
        if keyboard.is_pressed('x'):
            v.value = 1
            print("Child Terminate")
            sys.exit()
    #Child process's code

if __name__ == "__main__":
    val = Value('i', 0)
    p = Process(target=KeyboardScan, args=(val,))
    p.start()

    #Parent process's code

So if the key x is pressed, the Child should terminate the Parent and itself.

In this code the value exists only because originally I had a while loop in my Parent process to check for the value. If the value is 1 then it performs a sys.exit() on the Parent process.

But I'm trying to avoid using this method.

Any suggestions?

Upvotes: 0

Views: 2271

Answers (2)

bigh_29
bigh_29

Reputation: 2633

Consider using multiprocessing primitives to ensure a clean shutdown of both processes. Two ways to accomplish this:

  1. Code the child to simply exit when it detects the X. Have the parent occasionally check if the child process is still alive via p.is_alive or p.exitcode. If it isn't, then exit
  2. Move the keyboard detection back to the parent process. Signal that the child should exit by way of a shared multiprocessing.Event

You haven't said what your parent process is doing while the child is running. That impacts which of these two approaches is easier to utilize. I like the second approach because it feels right to me. I would rather have the parent deal with user input, and just have the child process do work that does not involve interacting with the user.

The code snippet below shows the second approach.

from multiprocessing import Process, Event
import atexit
import time
from random import randint

def child_main(e):
    print('Child process booted')
    while True:
        if e.is_set():
            print('Child process got terminate event. Exiting')
            return

        print('Child process doing some important work')
        time.sleep(1.0)

def parent_main():
    print("parent process booting")
    quit_event = Event()
    child = Process(target=child_main, args=(quit_event,))
    print('starting child')
    child.start()

    is_x_pressed = lambda: randint(0,8) == 0
    while True:
        print('Parent doing its thing')
        time.sleep(.5)

        if is_x_pressed():
            print("Parent detected X. Exiting")
            quit_event.set()
            return

if __name__== '__main__':
    def exit_hook():
        print('Parent process atexit handler')
    atexit.register(exit_hook)

    parent_main()
    print('parent exiting __main__')

Upvotes: 0

Adam.Er8
Adam.Er8

Reputation: 13393

you can use os module to get the ppid, and then .kill it.

try this:

from multiprocessing import Process, Value
import keyboard
import os
import signal
import sys
import psutil

def KeyboardScan(v):
    Paused = False
    while True:
        if keyboard.is_pressed('x'):
            v.value = 1
            print("Child Terminate")
            #os.kill(os.getppid(), signal.SIGTERM) # <=== if you don't have psutil
            # below 2 line depend on psutil
            p = psutil.Process(os.getppid())
            p.terminate()  #or p.kill()
            sys.exit()
    #Child process's code

if __name__ == "__main__":
    val = Value('i', 0)
    p = Process(target=KeyboardScan, args=(val,))
    p.start()

    #Parent process's code

Upvotes: 1

Related Questions