Python进程不会调用atexit

标签 python multiprocessing terminate atexit

我正在尝试使用 atexitProcess ,但不幸的是它似乎不起作用。下面是一些示例代码:

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/

相关文章:

c++ - 在函数中传递 vector 元素

python - multiprocessing.Pool 生成的进程多于仅在 Google Cloud 上请求的进程

scala - 如何结束无限的akka​​流

python - ipython:exit() 语句未按预期工作

python - Python 中未使用的导入会影响性能吗?

python - Groupby 和 reshape 长到宽格式的数据框

python - 如何将队列引用传递给 pool.map_async() 管理的函数?

python - 有没有办法杀死一个线程?

python - 一个类轮通过一个可迭代的(生成器)

python - 安装Python ez_setup.py