Understanding the frame parameter in python signal handlers
According to the documentation of python’s
signal module, signal handlers
accept two parameters. One is the obvious signum
. Another is the frame
.
What does it do? Is it some unnecessary implementation details that you should
ignore? The documentation is not very clear about it’s use cases.
frame is the way to know about the state of execution before the signal
handler was triggered. Since a signal is usually an asynchronous, external
event, you can not make any assumptions about the state of execution while
handling a signal. Actually, you don’t need to; as the information about the
state of the execution is sent to the signal handler through the frame
parameter. Using the frame
, a signal handler can read states inside the scope
that was being executed before the signal handler was triggered. An example
will clarify the process -
#!python
# file: signal_frame_demo.py
import signal
from time import sleep
def signal_handler(signum, frame):
print(
"Execution inside '{0}', "
"with local namespace: {1}"
.format(frame.f_code.co_name, frame.f_locals.keys()))
# Set a repeatitive alarm signal with 1 second interval.
signal.signal(signal.SIGALRM, signal_handler)
signal.setitimer(signal.ITIMER_REAL, 1.0, 1.0)
while True:
def my_first_sleepy_function():
# Some useless local variables to polute the namespace.
a, b, c = (1, 2, 3)
sleep(2.0)
def my_second_sleepy_function():
# Some useless local variables to polute the namespace.
x, y, z = (101, 102, 103)
sleep(2.0)
my_first_sleepy_function()
my_second_sleepy_function()
# sleep in the global namespace.
sleep(2.0)
Executing the above script prints something like this -
Execution inside 'my_first_sleepy_function', with local namespace: dict_keys(['b', 'c', 'a']) Execution inside 'my_second_sleepy_function', with local namespace: dict_keys(['y', 'x', 'z']) Execution inside '<module>', with local namespace: dict_keys(['__builtins__', 'my_first_sleepy_function', '__file__', '__package__', 'signal', '__spec__', 'signal_handler', '__name__', '__cached__', 'my_second_sleepy_function', '__doc__', 'sleep', '__loader__']) ... ...
Caution
frame
and most of it’s items are read only. For example, you can not add
a new variable to the execution environment by modifying frame.f_locals
.