退出父进程时退出while循环子进程?

Exit while-looped child process when parent process is exited?

我试图在父进程退出时关闭子进程(它正在执行 while 循环)(每当父进程干净退出、强制退出或因异常退出时),而不是让子进程成为僵尸进程过程。

我正在制作一个与 Arduino 通信的游戏(使用串口),主进程是 运行 Panda3D 的 ShowBase 实例(游戏引擎,做渲染和其他许多事情)所以主进程不能停止。
因此,我使用多处理模块创建了子进程,这样主进程就可以安全地停止等待串行输入。

但问题是,当我关闭 Panda3D window,调用 sys.exit() 或因异常退出时,主进程立即退出,无法加入或给子进程提供 false,所以子进程变成了僵尸。

我不知道如何解决这个问题。我应该怎么做才能让它像我预期的那样工作?

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from multiprocessing import Process, Queue
from panda3d.core import *

class HW_support:
    def hardware_event_handler(self, process_status):
        self.process_alive = True
        while self.process_alive:
            print('Working!')
            self.process_alive = process_status.get()
        return

if __name__ == '__main__':
    from direct.showbase.ShowBase import ShowBase
    import sys
    class TestApp(ShowBase):
        def __init__(self):
            ShowBase.__init__(self)
            self.process_status_argv = Queue()
            self.HW_sub_process = Process(target = HW_support().hardware_event_handler, args=(self.process_status_argv,))
            self.HW_sub_process.start()
            base.messenger.toggleVerbose()
            taskMgr.add(self.task_make_alive, 'task_make_alive')

            base.accept('escape', self.exit_taskloop)
        def exit_taskloop(self, task=None):
            taskMgr.stop()

        def task_make_alive(self, task=None):
            self.process_status_argv.put(True)
            return task.cont

    app = TestApp()
    app.run()
    #app.HW_sub_process.join()
    app.process_status_argv.put(False)

多个进程使事情变得更加复杂。

要干净地关闭 HW_support 进程,您需要通过 Queue 对象向它发送消息,然后父级需要 join() 它(等待它退出) 在退出之前。

任何可能使父级意外退出的事件(控制台中断、抛出的异常、sys.exit 等)都需要仔细捕获和管理,以便您仍然可以在退出前干净利落地关闭子级。

在主程序中将其添加到顶部(远低于 import multiprocessing

if multiprocessing.current_process().name == 'MainProcess':
    import atexit
    atexit.register(lambda *a : os.remove("running.txt"))
    open("running.txt","wb").close()

在子过程中将您的 while True 循环更改为 while os.path.exists("running.txt"):

或者,您可以让 atexit 在队列中放置一条消息,或者做任何事情来向子进程发出它应该退出的信号。