Table of Contents
Übung 3
UNIX-Signale, Nebenläufigkeit, Duplizieren von Dateideskriptoren, Aufgabe 3
Folien ⨳ Aufgabe (rush) ⨳ API-Doku (rush)
DISCLAIMER: Die Beispiele stehen hier so, wie in der Übung gemeinsam erarbeitet. Der Code lässt sich nicht eins zu eins zur Abgabe kopieren. Der Einfachheit halber ist einiges abgekürzt und es fehlen unter anderem einige Fehlerbehandlungen.
Beispiel: sigexample
Ein Program, das auf drei SIGUSR1
Signale wartet und sich dann beendet:
static volatile int event = 0;
static void
static void
int
Was in der Signalbehandlung zu beachten ist:
errno
sichern, wenn sie während der Funktion überschrieben werden könnte- Gemeinsame Datenstrukturen durch
sigprocmask(3p)
einseitig synchronisieren - Keine Funktionen mit Filepointern verwenden, da diese mit einem Lock synchronisiert sind (Deadlock). Dies betrifft auch
fprintf(3p)
und Co. - Im Signal-Handler selber sollten keine Signale mit
sigprocmask(3p)
mehr blockiert werden. Hierzu ist dassa_mask
Feld desstruct sigaction
da. Das behandelte Signal ist in der Behandlung automatisch blockiert. - Wenn das Signal während der Behandlung nochmal eintrifft wird es hinterher stets nur einmal zugestellt. Dementsprechend müssen manche Aufrufe (z.B.
waitpid(3p)
) in einer Schleife ausgeführt werden.
Der Unterschied sigprocmask(3p)
und sigaction(3p)
:
Auf den ersten Blick scheinen sigprocmask(3p)
und sigaction(3p)
mit SIG_IGN
einen ähnlichen Effekt zu haben. Tatsächlich sind diese Aufrufe jedoch keinesfalls gegenseitig auswechselbar.
sigaction(3p)
mit SIG_IGN
führt dazu, dass Signale vom entsprechenden Typen ignoriert werden. Auch wenn für Signal hinterher wieder Behandlungsroutine eingerichtet wird, werden verpasste Signale nicht nachträglich zugestellt.
sigprocmask(3p)
blockiert ein Signal temporär. Sobald die ursprüngliche Signalmaske wiederhergestellt wird wird das Signal zugestellt.
Die Verwechselung der beiden kann dazu führen, dass entweder wichtige Signal verloren gehen oder Signale auf einmal zu einem unerwarteten Zeitpunkt, stark verzögert zugestellt werden (z.B. nachdem ein Kindprozess nach fork(3p)
und execvp(3p)
die Signalmaske zurücksetzt).