我正在尝试使用 atexit
在 Process
,但不幸的是它似乎不起作用。下面是一些示例代码:
import time
import atexit
import logging
import multiprocessing
logging.basicConfig(level=logging.DEBUG)
class W(multiprocessing.Process):
def run(self):
logging.debug("%s Started" % self.name)
@atexit.register
def log_terminate():
# ever called?
logging.debug("%s Terminated!" % self.name)
while True:
time.sleep(10)
@atexit.register
def log_exit():
logging.debug("Main process terminated")
logging.debug("Main process started")
a = W()
b = W()
a.start()
b.start()
time.sleep(1)
a.terminate()
b.terminate()
这段代码的输出是:
DEBUG:root:Main process started DEBUG:root:W-1 Started DEBUG:root:W-2 Started DEBUG:root:Main process terminated
I would expect that the W.run.log_terminate()
would be called when a.terminate()
and b.terminate()
are called, and the output to be something likeso (emphasis added)!:
DEBUG:root:Main process started DEBUG:root:W-1 Started DEBUG:root:W-2 Started DEBUG:root:W-1 Terminated! DEBUG:root:W-2 Terminated! DEBUG:root:Main process terminated
Why isn't this working, and is there a better way to log a message (from the Process
context) when a Process
is terminated?
Thank you for your input - it's much appreciated.
Solution
EDIT: Based on solution suggested by Alex Martelli, the following works as expected:
import sys
import time
import atexit
import signal
import logging
import multiprocessing
logging.basicConfig(level=logging.DEBUG)
class W(multiprocessing.Process):
def run(self):
logging.debug("%s Started" % self.name)
def log_terminate(num, frame):
logging.debug("%s Terminated" % self.name)
sys.exit()
signal.signal(signal.SIGTERM, log_terminate)
while True:
time.sleep(10)
@atexit.register
def log_exit():
logging.debug("Main process terminated")
logging.debug("Main process started")
a = W()
b = W()
a.start()
b.start()
time.sleep(1)
a.terminate()
b.terminate()
值得注意的是 <a href="http://docs.python.org/library/atexit.html" rel="noreferrer noopener nofollow">atexit</a>
中的以下评论文档:
Note: the functions registered via this module are not called when the program is killed by a signal, when a Python fatal internal error is detected, or when os._exit() is called.
最佳答案
作为 the docs说,
On Unix this is done using the SIGTERM signal; on Windows TerminateProcess() is used. Note that exit handlers and finally clauses, etc., will not be executed.
如果你在 Unix 上,你应该可以用 signal 拦截 SIGTERM
,并执行您需要的任何“终止事件”;但是,我不知道跨平台解决方案。
关于Python进程不会调用atexit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2546276/