【问题标题】:How to make a python context manager catch a SIGINT or SIGTERM signal如何让 python 上下文管理器捕获 SIGINT 或 SIGTERM 信号
【发布时间】:2020-10-19 21:22:05
【问题描述】:

我使用上下文管理器流式传输数据以在程序退出时关闭连接。我在后台将我的程序作为守护进程运行。

当守护程序被 SIGINT 或 SIGTERM 或 kill 命令发送的任何中断信号中断时,我如何让上下文管理器处理这种情况?

我在 Raspberry Pi 和 Ubuntu 上运行 Python 3。

更新

我看过这个:How do I capture SIGINT in Python? 哪个有帮助,但我不确定如何将它与 python 的上下文管理器一起使用? IE。假设我有一个作为上下文管理器构建的对象:

class Sensor:

    def __init__(self, name: str):
        self.name = name

    def __enter__(self):
        self._connect()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()

我在作为守护进程运行的脚本中使用该对象。是否有一种 Pythonic 方式来指定在 SIGINT 和 SIGTERM 异常上也必须调用 __ exit__ 函数?

抱歉,如果没有正确理解异常和信号中断在 python 中的工作原理,并且我的问题没有意义

【问题讨论】:

  • 这能回答你的问题吗? How do I capture SIGINT in Python?
  • 不完全是,我已经更新了这方面的问题
  • 你的上下文管理器已经SIGINT工作了吗?
  • 你需要注册你想调用的函数作为信号处理程序,例如self.close
  • 是的,它可能已经按照您的预期工作了,因为它是一个上下文管理器。您能否显示minimal reproducible example,当您使用 kill 命令时脚本无法按预期工作?

标签: python process sigint sigterm


【解决方案1】:

您可以为调用sys.exit() 的上下文管理器创建一个内部方法(例如_handle_interrupt),并在调用__enter__ 时将其注册为信号处理程序:

class Sensor:

    def __init__(self, name: str):
        self.name = name

    def _handle_interrupt(self):
       sys.exit()  # will trigger a exception, causing __exit__ to be called

    def __enter__(self):
        signal.signal(signal.SIGINT, self._handle_interrupt)
        signal.signal(signal.SIGTERM, self._handle_interrupt)
        self._connect()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()

您还应该查看PEP 419,这可能对您的设置有所帮助。 至于您对线程的要求,如果没有更多信息,很难说清楚。

【讨论】:

猜你喜欢
  • 2020-07-03
  • 1970-01-01
  • 2021-10-01
  • 2017-08-22
  • 2017-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多