interface, the script in Example 5-27 installs a Python handler function for the signal
number passed in as a command-line argument.
Example 5-27. PP4E\System\Processes\signal1.py
"""
catch signals in Python; pass signal number N as a command-line arg,
use a "kill -N pid" shell command to send this process a signal; most
signal handlers restored by Python after caught (see network scripting
chapter for SIGCHLD details); on Windows, signal module is available,
but it defines only a few signal types there, and os.kill is missing;
"""
import sys, signal, time
def now(): return time.ctime(time.time()) # current time string
def onSignal(signum, stackframe): # python signal handler
print('Got signal', signum, 'at', now()) # most handlers stay in effect
signum = int(sys.argv[1])
signal.signal(signum, onSignal) # install signal handler
while True: signal.pause() # wait for signals (or: pass)
There are only two signal module calls at work here:
signal.signal
Takes a signal number and function object and installs that function to handle that
signal number when it is raised. Python automatically restores most signal handlers
when signals occur, so there is no need to recall this function within the signal
handler itself to reregister the handler. That is, except for SIGCHLD, a signal handler
remains installed until explicitly reset (e.g., by setting the handler to SIG_DFL to
restore default behavior or to SIG_IGN to ignore the signal). SIGCHLD behavior is
platform specific.
signal.pause
Makes the process sleep until the next signal is caught. A time.sleep call is similar
but doesn’t work with signals on my Linux box; it generates an interrupted system
call error. A busy while True: pass loop here would pause the script, too, but may
squander CPU resources.
Here is what this script looks like running on Cygwin on Windows (it works the same
on other Unix-like platforms like Linux): a signal number to watch for (12) is passed
in on the command line, and the program is made to run in the background with an
& shell operator (available in most Unix-like shells):
[C:\...\PP4E\System\Processes]$ python signal1.py 12 &
[1] 8224
$ ps
PID PPID PGID WINPID TTY UID STIME COMMAND
I 8944 1 8944 8944 con 1004 18:09:54 /usr/bin/bash
8224 7336 8224 10020 con 1004 18:26:47 /usr/local/bin/python
Interprocess Communication | 241