Lee M.U. Lee M.U. - 1 month ago 15
Python Question

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

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)

Answer

in the main program add this at the top (well below import multiprocessing)

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

in the subprocces change your while True loop to while os.path.exists("running.txt"):

alternatively you could have atexit place a message in the queue or do whatever to signal to the subprocess that it should exit.

Comments