18

我正在查看 Python 文档中的信号和示例代码:

def handler(signum, frame):
    print 'Signal handler called with signal', signum
    raise IOError("Couldn't open device!")

'frame' 参数未在实际函数中使用。我在 stackoverflow/online 上关于信号处理程序的大量代码中注意到了这一点。什么是“框架”参数?为什么它保存在函数头中?

谢谢

4

3 回答 3

20

frame 参数是堆栈帧,也称为执行帧。它指向被信号中断的帧。该参数是必需的,因为任何线程都可能被信号中断,但信号仅在主线程中接收。

例子:

import signal
import os
import traceback

def handler(signum, frame):
    print signum, frame
    print "print stack frames:"
    traceback.print_stack(frame)

def demo(n):
    if n == 3:
        os.kill(os.getpid(), signal.SIGUSR1)
        return
    demo(n+1)

signal.signal(signal.SIGUSR1, handler)
demo(1)

输出:

$ python t.py
10 <frame object at 0x1e00520>
print stack frames:
  File "t.py", line 17, in <module>
    demo(1)
  File "t.py", line 14, in demo
    demo(n+1)
  File "t.py", line 14, in demo
    demo(n+1)
  File "t.py", line 12, in demo
    os.kill(os.getpid(), signal.SIGUSR1)
于 2013-09-09T19:14:10.527 回答
5

frame 参数是Python 堆栈帧。摘自手册:

使用两个参数调用处理程序:信号编号和当前堆栈帧(无或帧对象;有关帧对象的描述,请参阅类型层次结构中的描述或查看检查模块中的属性描述)。

在您看到的示例中,它经常被忽略,因为它在 Python 调试器之外并不是特别有用。信号是异步的并且会不择手段地触发一个进程。如果我将 SIGTERM 发送到您的进程并且您已设置好处理它,那么您的代码在收到信号时所在的位置通常是无关紧要的。

于 2013-09-09T19:10:35.717 回答
3

这是当前的堆栈帧

例如,在中止某些信号之前打印当前堆栈信息可能很有用。

于 2013-09-09T19:09:47.360 回答