【问题标题】:Need to understand Python signals and modules需要了解 Python 信号和模块
【发布时间】:2010-03-24 23:16:48
【问题描述】:

我正在尝试跟上 Python 的速度,尝试用它替换一些 C。我遇到了在模块之间共享数据的问题,或者更可能是我对整个事情的理解。我有一个简化的信号模块:

import sys, signal

sigterm_caught = False

def SignalHandler(signum, stackframe):
  if signum == signal.SIGTERM:
    sigterm_caught = True
    sys.stdout.write("SIGTERM caught\n")

def SignalSetup():
  signal.signal(signal.SIGTERM, SignalHandler)

我的主代码有一个这样的循环:

signals.SignalSetup()
while signals.sigterm_caught == False:
  sys.stdout.write("sigterm_caught=%s\n" % str(signals.sigterm_caught))
  time.sleep(5)

我运行它,然后终止进程,在 signals.py 中它获取信号,将 sigterm_caught 设置为 True,但主进程中的循环没有看到 sigterm_caught 值的变化。

那么 (a) 我的方法对于 Python 方式来说是完全错误的吗? (b) 我在尝试引用模块中的变量时是否做错了什么? (c) 我应该以不同的方式处理信号,比如引发异常吗?

补充: 通过引发异常来处理信号更好,还是我的旧 C 方法仍然有效?

【问题讨论】:

    标签: python module signals


    【解决方案1】:

    您需要在处理程序中添加global 语句:

    def SignalHandler(signum, stackframe):
      global sigterm_caught
      if signum == signal.SIGTERM:
        sigterm_caught = True
        sys.stdout.write("SIGTERM caught\n")
    

    默认情况下,Python 编译器将每个名称(如 sigterm_caught)视为函数的本地,如果函数似乎分配给该名称; global 语句的作用是反转此默认值,以便 Python 编译器将名称视为 global(即模块级顶级名称)。

    【讨论】:

    • 是通过引发异常来处理信号更好,还是全局变量方法仍然有效?
    • @codebunny,您应该“异步”引发的唯一异常(即,来自与正在运行的代码无关的外部原因)是KeyboardInterrupt;通过该异常(或其子类)汇集所有信号是可能的,但恕我直言,在可行的情况下,您的替代方案是可取的(意见可能不同;-)。
    【解决方案2】:

    如果您要写入全局变量,请使用 global:

    sigterm_caught = False
    
    def SignalHandler(signum, stackframe):
      global sigterm_caught
      if signum == signal.SIGTERM:
        sigterm_caught = True
        sys.stdout.write("SIGTERM caught\n")
    

    【讨论】:

    • 这可以在课堂上使用吗?在 init 中给出“全局 self.variable”后,我无法通过其他方法中的信号处理程序访问设置为 self.variable 的值。
    猜你喜欢
    • 1970-01-01
    • 2012-06-01
    • 2013-10-13
    • 2014-06-12
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 2011-09-09
    • 2012-01-26
    相关资源
    最近更新 更多