【问题标题】:Python Process won't call atexitPython进程不会调用atexit
【发布时间】:2011-02-02 12:40:15
【问题描述】:

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

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:主进程启动 DEBUG:root:W-1 开始 调试:根:W-2 开始 DEBUG:root:主进程终止

我希望W.run.log_terminate() 会在a.terminate()b.terminate() 被调用时被调用,并且输出是类似的东西(添加了重点)!:

DEBUG:root:主进程启动 DEBUG:root:W-1 开始 调试:根:W-2 开始 DEBUG:root:W-1 终止! DEBUG:root:W-2 终止! DEBUG:root:主进程终止

为什么这不起作用,当Process 终止时,是否有更好的方法来记录消息(来自Process 上下文)?

感谢您的意见 - 非常感谢。

解决方案

编辑:基于 Alex Martelli 建议的解决方案,以下工作按预期工作:

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()

值得注意的是@987654321@ 文档中的以下注释:

注意:当程序被信号杀死、检测到 Python 致命内部错误或调用 os._exit() 时,不会调用通过此模块注册的函数。

【问题讨论】:

    标签: python multiprocessing terminate atexit


    【解决方案1】:

    正如the docs 所说,

    在 Unix 上,这是使用 SIGTERM 完成的 信号;在 Windows TerminateProcess() 上 用来。请注意,退出处理程序和 finally 子句等不会 执行。

    如果你在 Unix 上,你应该能够拦截 SIGTERMsignal,并执行你需要的任何“终止活动”;但是,我不知道跨平台的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-10
      • 2017-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多