1

I'm trying to close child process(which is doing while loop) when parent process is exited (Whenever parent process is clean-exit, forced-exit or exited because of exception) not to make child process a zombie process.

I'm making a game that communicates with Arduino (using serial), and main process is running Panda3D's ShowBase instance(Game engine, do render and another many things) so main must not be stopped.
So, I created subprocess using multiprocessing module so that main process is safe from stopping to wait serial in.

But the problem is, when i close Panda3D window, call sys.exit() or exited because of exception, main process exits immediately, and can't join or give false to subprocess, so subprocess becomes zombie.

I have no idea how to solve this. What should i do to make it work as i expected?

#!/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)
4

2 回答 2

1

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

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

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

于 2016-11-03T18:37:33.500 回答
1

在主程序的顶部添加这个(远低于import multiprocessing

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

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

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

于 2016-11-03T18:39:18.493 回答