当前位置: 首页 > 面试题库 >

Python进程不会调用atexit

卞浩漫
2023-03-14
问题内容

我试图用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:W-1已开始
DEBUG:root:W-2已开始
DEBUG:root:主进程终止

我希望W.run.log_terminate()可以在a.terminate()和被调用时b.terminate()调用,并且输出将类似于(强调)!:

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

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

感谢您的输入-非常感谢。

编辑: 根据亚历克斯·马特利(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()

值得在[atexit](http://docs.python.org/library/atexit.html)文档中注意以下注释:

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


问题答案:

正如文档所说,

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

如果您使用的是Unix,则应该能够SIGTERM使用signal进行拦截,并执行所需的任何“终止活动”;但是,我不知道跨平台的解决方案。



 类似资料:
  • 问题内容: 我正在编写一个程序,它将监视特定目录中包含下载URL的新文件。一旦检测到新文件,它将在父级继续监视目录的同时创建一个新过程来进行实际下载。我正在使用来自的界面。我的问题是,除非我调用process.join(),否则子进程仍在运行,但是process.join()是一个阻止函数,无法实现创建子进程来处理实际下载的目的。 我的问题是,是否有一种以非阻塞方式加入子进程的方法,该方法将允许父

  • 问题内容: Python版本:2.6.7 我在for循环中有以下subprocess.call,该循环被执行18次,但是,该过程始终挂在第19个循环上: 控制台输出如下所示: 由于我对python脚本不是很熟悉,所以我只是在徘徊我是否在做错什么…我怀疑某个地方出现了死锁。 会处理这些问题吗? 在什么情况下subprocess.call会挂起任何专家答案?非常感谢 问题答案: 当使用子过程时,我倾向

  • 问题内容: 我想从我的C ++程序中调用python脚本文件。 我不确定要分发给的人是否会安装python。 基本上,我正在寻找一个可以使用的具有Apache类似发行许可证的.lib文件。 问题答案: Boost有一个python接口库可以为您提供帮助。 Boost.Python

  • 导致错误: Traceback(最近一次调用最后一次):文件C:\Program Files(x86)\wing IDE 101 5.0\src\debug\tserver_sandbox.py,第3行,在传递文件c:\Python27\Lib\subprocess.py,第172行,在调用返回Popen(*popenargs,**kwargs). etc()文件c:\Python27\Lib\s

  • 我是spring webflux和reactor的新手,我希望在发生某些特定异常时有一个回退机制,根据我的研究,onErrorResume方法可以做到这一点,但它不会被调用,我得到500个内部服务器错误,而不是触发回退并阻止此错误。 注意:我使用Spring网络流量,这意味着它在Reactor项目的正常行为中做了一些改变 这是堆栈跟踪

  • 问题内容: 我正在使用Python脚本来调用Java虚拟机。以下命令有效: 但, 不起作用。避免使用Python文档建议。 问题答案: 您需要将命令拆分为单独的字符串: 在以下情况下可以使用字符串,但是在以下情况下您需要一个参数列表 该shlex模块是很有用的更因此对于更复杂的命令和处理输入,但良好的了解: shlex tut