signal

Signale sind integrer Bestandteil der Interprozesskommunikation unter unixoiden Betriebssystemen wie Linux. Hier verwendet man Signale beispielsweise, um schlafende Prozesse anzustoßen und sie so darüber zu informieren, dass ein Timer abgelaufen ist oder man sie gerne beenden würde. Um das zu realisieren kann das Programm Signal-Handler registrieren, Funktionen, die aufgerufen werden, sobald dieses oder jenes Signal eintrifft. Außerdem wird die Systemfunktion "pause" verwendet, um die Programmausführung solange anzuhalten, bis eines der gefragten Signale eintrifft.

Auch für Python gibt es eine Bibliothek, mit der man Signal-Handler registrieren und die "pause"-Funktion verwenden kann. Das Paket heißt "signal" und enthält neben einigen Konstanten für die numerischen Werte der Signale unter Anderem die beiden Funktionen "signal" und "pause".

Mit "signal" kann man einen Signal-Handler registrieren:

import signal

def mein_signal_handler(*args):
print 'signal erhalten!'

signal.signal(signal.SIGUSR1,mein_signal_handler)

import time
time.sleep(3600)

Schickt man dem Programm nun eines der Signale, für die es einen Handler registriert hat (im Beispiel USR1), wird dieser aufgerufen. Die letzten beiden Zeilen sorgen dafür, dass sich das Programm nicht nach dem registrieren des Signal-Handlers automatisch beendet. Das Warten bei "time.sleep" wird jedoch beim Empfangen eines Signales abgebrochen. Signale kann man unter Linux mit dem Kommandozeilenprogramm "kill" verschicken:

kill -SIGUSR1 [PID des Programmes]

Hat man ein Programm, dass ständig im Hintergrund läuft (Daemon) und dort schläft, bis eine Aufgabe eintrudelt, was ihm von einem Signal mitgeteilt wird, ist eine Endlosschleife zusammen mit der Funktion "pause" sinnvoll. Mit ihr kann sich das Programm solange schlafen legen, bis es eines der gewünschten Signale erhält, sich dann darüber erkundigen, was ansteht, die Aufgabe ausführen, und sich anschließend wieder schlafen legen:

import signal

def mein_signal_handler(*args):
print 'Signal erhalten!'

signal.signal(signal.SIGUSR1,mein_signal_handler)

while 1:
signal.pause()
print 'Aufgewacht, an die Arbeit!'
print '...'
print 'Fertig!'

Diesem Programm kann man beliebig oft das Signal schicken, es wird jedes Mal wieder aufwachen, die anstehende Aufgabe abarbeiten und sich wieder schlafen legen.

Vielen Dank an der Stelle an meinen Freund Thomas, der mir das Modul "signal" gezeigt hat.

Tags: Python