我正在尝试修复一个Python3应用程序,其中由各种队列和管道控制了多个专用和线程。当某人试图用CTRL-C打破程序时,我正在尝试做出一种受控退出的形式。但是,没有马瑟(Mather(我所做的事情总是挂在最后。
我尝试使用键盘间隔异常和信号捕获以下代码是多过程代码的一部分。
from multiprocessing import Process, Pipe, JoinableQueue as Queue, Event
class TaskExecutor(Process):
def __init__(....)
{inits}
def signal_handler(self, sig, frame):
print('TaskExecutor closing')
self._in_p.close()
sys.exit(1)
def run
signal.signal(signal.SIGINT, self.signal_handler)
signal.signal(signal.SIGTERM, self.signal_handler)
while True:
# Get the Task Groupe name from the Task queue.
try:
ExecCmd = self._in_p.recv() # type: TaskExecCmd
except Exceptions as e:
self._in_p.close()
return
if ExecCmd.Kill:
self._log.info('{:30} : Kill Command received'.format(self.name))
self._in_p.close()
return
else
{other code executing here}
我要收到上述印刷品。但是我仍然得到很多不同的例外,我试图捕获,但不会。
我正在寻找一些文档,以关闭多过程及其主要过程。
我知道这是非常普遍的问题,但是它是一个很大的应用程序,因此,如果我可以测试任何问题或东西,我可以将其缩小。
问候
因此,在进一步研究了此问题后,我发现在我有一个管道线,队列线程和4个多进程的情况下。这些过程中的#在用CTRL-C终止应用程序时可能会挂起。管道和队列过程已经关闭。
在多处理文档中有警告。
警告是否使用此方法在使用的过程中使用 管道或排队 其他过程可能会变得无法使用。同样,如果该过程具有 获得了锁或信号量等。然后终止它是有责任的 导致其他过程僵局。
我认为这就是正在发生的事情。我还发现,即使我在多进程类中具有关闭机制,即使我知道 run run((方法已返回,即内部悬挂。
现在的解决方案。我的多进程是用于设计视图而不是戴蒙,因为我想控制它们的投篮。但是,我将它们更改为Deamon,因此无论如何它们都会被杀死。我首先补充说,任何人杀死信号都会提高和 ProgramKilled 在整个程序中例外。
def signal_handler(signum, frame):
raise ProgramKilled('Task Executor killed')
然后,我将我的多过程类中的关闭机制更改为
while True:
# Get the Task Groupe name from the Task queue.
try:
# Reading from pipe
ExecCmd = self._in_p.recv() # type: TaskExecCmd
# If fatal error just close it all
except BrokenPipe:
break
# This can occure close the pipe and break the loop
except EOFError:
self._in_p.close()
break
# Exception for when a kill signal is detected
# Set the multiprocess as killed (just waiting for the kill command from main)
except ProgramKilled:
self._log.info('{:30} : Died'.format(self.name))
self._KilledStatus = True
continue
# kill command from main recieved
# Shut down all we can. Ignore exceptions
if ExecCmd.Kill:
self._log.info('{:30} : Kill Command received'.format(self.name))
try:
self._in_p.close()
self._out_p.join()
except Exception:
pass
self._log.info('{:30} : Kill Command executed'.format(self.name))
break
else if (not self._KilledStatus):
{Execute code}
# When out of the loop set killed event
KilledEvent.set()
,在我的主线程中,我添加了以下清理过程。
#loop though all my resources
for ThreadInterfaces in ResourceThreadDict.values():
# test each process in each resource
for ThreadIf in ThreadInterfaces:
# Wait for its event to be set
ThreadIf['KillEvent'].wait()
# When event have been recevied see if its hanging
# We know at this point every thing have been closed and all data have been purged correctly so if its still alive terminate it.
if ThreadIf['Thread'].is_alive():
try:
psutil.Process(ThreadIf['Thread'].pid).terminate()
except (psutil.NoSuchProcess, AttributeError):
pass
af很多测试,我知道很难控制具有多个过程的终止和应用程序的终止,因为您根本不知道所有过程都会收到此信号的顺序。
我试图在某种程度上试图在杀死数据时保存大多数数据。有些人会争论我在手动终止应用程序时需要的数据。但是在这种情况下,此应用程序运行了许多外部脚本和其他应用程序,其中任何一个都可以锁定该应用程序,然后您需要手动杀死它,但仍保留已执行的信息的信息。
所以这是我目前知识解决当前问题的方法。欢迎任何有关发生的事情的输入或更多深入的知识。请注意,此应用程序同时在Linux和Windows上运行。
问候