如何终止多处理父流程?

时间:2019-07-11 18:06:21

标签: python multiprocessing python-multiprocessing

如何让子进程终止父进程?

我在想……的事情

子级获取父级进程的PID,并使用psutil

终止父级

这是我的代码

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

因此,如果按下键x,则孩子应终止父项及其本身。

在此代码中,value的存在仅是因为最初我在Parent进程中有一个while循环来检查该值。如果值为1,则它将在父进程上执行sys.exit()

但是我试图避免使用这种方法。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

您可以使用os模块来get the ppid,然后使用.kill it

尝试一下:

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

答案 1 :(得分:0)

请考虑使用多处理原语来确保两个进程的干净关闭。实现此目的的两种方法:

  1. 编码子进程以使其在检测到X时简单退出。让父进程偶尔通过p.is_alivep.exitcode检查子进程是否仍然存在。如果不是,则退出
  2. 将键盘检测移回父进程。表示孩子应该通过共享的multiprocessing.Event
  3. 退出

您还没有说孩子运行时父进程正在做什么。这影响了这两种方法中哪种更易于使用。我喜欢第二种方法,因为它适合我。我宁愿让父级处理用户输入,而让子级进程执行不涉及与用户交互的工作。

下面的代码段显示了第二种方法。

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__')