退出父进程时退出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 在队列中放置一条消息,或者做任何事情来向子进程发出它应该退出的信号。
我试图在父进程退出时关闭子进程(它正在执行 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 在队列中放置一条消息,或者做任何事情来向子进程发出它应该退出的信号。