2010-03-24 56 views
3

我试图用Python来加快速度,尝试用它替换一些C。我遇到了模块之间共享数据的问题,或者更可能是我对整个事物的理解。我有一个简单的信号模块:需要了解Python信号和模块

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值的变化。

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

此外: 通过引发异常来处理信号还是我的旧C方法仍然是有效的?

回答

7

你需要一个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编译器将该名称视为全局(即模块级别的顶级名称)。

+0

工程。谢谢。我最好重新阅读一下Python范围。 – codebunny 2010-03-24 15:12:08

+0

通过引发异常来处理信号还是全局变量方法仍然有效? – codebunny 2010-03-24 15:17:30

+1

@codebunny,你唯一应该“异步”引发的异常(即来自与正在运行的代码无关的外部原因)是'KeyboardInterrupt';通过这个例外(或其子类)汇集所有信号是一种可能性,但恕我直言,在可行的情况下,您的替代方案更可取(意见可能不同;-)。 – 2010-03-24 15:35:57

3

如果你是写作到一个全局变量,使用全局:

sigterm_caught = False 

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

这将在课堂上工作吗?在__init__中给出'global self.variable'后,我无法通过其他方法中的信号处理程序访问设置为self.variable的值。 – Vivek 2012-05-17 12:44:38