我有一个 Python 程序,它有多个进程(目前只有 2 个)和线程(每个进程 2 个)。我想捕获每个异常,特别是通过 Ctrl+c 干净地关闭我的程序,但我无法让它工作。每次发生异常时,程序都会停止,但无法正确关闭,从而导致命令行无法使用。
到目前为止,我在伪代码中尝试过的是:
try:
for process in processes:
process.join()
except:
pass #Just to suppress error-messages, will be removed later
finally:
for process in processes:
process.terminate()
但正如我已经说过的,没有运气。另请注意,我收到两个进程的异常错误消息,因此我相信它们都已停止?
也许我还应该提到大多数线程在侦听管道时被阻止。
编辑
所以我几乎让它工作了。我需要尝试:
每个线程并确保线程正确连接。只有一个缺陷:Exception KeyboardInterrupt in 关闭时忽略
。这是在主进程的主线程中引发的。该线程已经完成,这意味着它已经通过了最后一行代码。
I have a Python program that has several processes (for now only 2) and threads (2 per process). I would like to catch every exception and especially shut down my program cleanly on Ctrl+c but I can't get it to work. Everytime an Exception occurs the program stops but does not shut down correctly, leaving me with an unusable commandline.
What I have tried so far in pseudocode is:
try:
for process in processes:
process.join()
except:
pass #Just to suppress error-messages, will be removed later
finally:
for process in processes:
process.terminate()
But as I already said with no luck. Also note, that I get the Exception error message for both Processes, so they are both halted I believe?
Maybe I should also mention that most of the threads are blocked in listening on a pipe.
EDIT
So I nearly got it working. I needed to try:
every thread and make sure the threads are joined correctly. There is just one flaw: Exception KeyboardInterrupt in <module 'threading' from '/usr/lib64/python2.7/threading.pyc'> ignored
when shutting down. This is raised in the main-thread of the main-process. This thread is already finished, meaning it has passed the last line of code.
发布评论
评论(1)
问题(我预计)是异常是在进程内部引发的,而不是在连接调用中引发的。
我建议您尝试将每个进程的主要方法包装在 try- except 循环中。然后将 except 语句设置为 False 的标志(例如 multiprocessing.Value 的实例)。每个进程都可以检查标志的值,如果标志设置为 False,则停止(自行清理)。
请注意,如果您只是终止一个进程,它不会自行清理,因为这与向其发送 SIG_TERM 相同。
The problem (I expect) is that the exceptions are raised inside the processes not in the join calls.
I suggest you try wrapping each process's main method in try-except loop. Then have a flag (e.g. an instance of multiprocessing.Value) that the except statement sets to False. Each process could check the value of the flag and stop (cleaning up after itself) if it's set to False.
Note, if you just terminate a process it won't clean up after itself, as this is the same as sending a SIG_TERM to it.