需要理解Python信号和模块

3 投票
2 回答
5709 浏览
提问于 2025-04-15 20: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语言中的做法仍然有效呢?

2 个回答

3

如果你要对一个全局变量进行写入操作,记得使用 global 关键字:

sigterm_caught = False

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

你需要在处理函数里加一个 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 语句的作用就是告诉编译器,这个名字是全局的,也就是在整个模块中都能用。

撰写回答