ein Kapitel zurück                                           ein Kapitel weiter

Auf Linuxsystemen gibt es außer dem von ANSI-C vorgeschriebenen Signalkonzept noch ein besseres Konzept. Dies wurde entwickelt da beim alten Signalkonzept folgendes zu Bemängeln war......

  • Erfragen des akutellen Signalstatuses war nicht so ohne weiteres möglich
  • Konlikte zwischen 2 gleichen Signalen im selben Programm. Beispielsweise SIGINT. Ein Signalhandler soll diese Funktion ignorieren und ein anderer eine bestimmte Fuktion ausführen. Dies können durcheinandergeraten.


Dafür wurde das neue Signalkonzept gemacht.

Zuerst benötigen wir eine Variable vom primitven Datentypen sigset_t Beispielsweise....

sigset_t signal_menge;  

Zuerst müssen wir die Signalmenge initialisieren mit der Funktion sigemptyset........

#include <signal.h>

int sigemptyset(sigset_t *sig_m);  

Mit dieser Funktion werden alle Signalmengen aus sig_m entfernt und gleichzeitg wird die Variable hiermit initialisiert. Mit dem Beispiel unserer Variable sieht dies jetzt folgendermaßen aus........

sigset_t signal_menge;

sigsetempty(&signal_menge);  

Da wir ja jetzt eine Art Maske für unsere Signalmenge haben, können wir fröhlich neue Signale für diesen Prozeß hinzufügen. Dies machen wir mit der Funktion.......

#include <signal.h>

int sigaddset(sigset_t *sig_m, int signr);  

Die Signalemenge sig_m ist die selbe die wir mit sigemptyset initialiert haben. signr sind die Signale die sie der Signalmenge hinzufügen wollen. Auch hier sei geraten den symbolischen Namen zu verwenden. Weiter zu unserem Beispiel......

sigset_t signal_menge;

sigemptyset(&signal_menge);
sigaddset(&signal_menge, SIGINT);
sigaddset(&signal_menge, SIGCHLD);  

Hier haben wir SIGINT und SIGCHLD zu unserer Signalmenge hinzugefügt. Im Gegensatz dazu könnten sie mit der Funkion....

#include <signal.h>

int sigdelset(setsig_t *sig_m, int signr);  

...das Signal signr aus der Signalmenge sig_m entfernen. Wollen sie jetzt überprüfen ob ein Signal in der Menge vorhanden ist um es anschließend zu setzen, falls es noch nicht vorhanden ist, können sie folgende Funktion benutzen.......

#include <signal.h>

int sigismember(sigset_t sig_m,int signr);  

Wenn ein Signal in der Signalmenge vorhanden ist gibt diese Funktion 1 zurück. Falls nicht dann 0.
In unserem Beispiel........

sigset_t signal_menge;

sigemptyset(&signal_menge);
sigaddset(&signal_menge, SIGINT);
if( (sigismember(&signal_menge, SIGCHLD)) == 0)
  sigaddset(&signal_menge, SIGCHLD);
else
  printf("SIGCHLD ist bereits in dieser Signalmenge vorhanden!!\n");  

Irgendwann werden sie mal vorhaben die Signalmaske zu Erfragen oder sie zu verändern. Dafür steht Ihnen die Funktion........

#include <signal.h>

int sigprocmask(int wie, const sigset_t *sig_m, sigset_t *alt_sig_m);  

Dabei unterscheidet diese Fuktion sich in 3 Fällen...

  • sigprocmask(wie, NULL, alt_sig_m);
    Hiermit wird die, im gerade laufenden Prozeß, Signalmenge in die Adresse alt_sig_m geschrieben. 'wie' hat in diesem Fall keinen Effekt.
  • sigprocmask(wie, sig_m, NULL);
    Signalmaske wird geändert. Zu 'wie' kommen wir gleich.
  • sigprocmask(wie, sig_m, alt_sig_m);
    Zuerst wird die aktuelle im laufenden Prozeß verwendete Signalmaske in alt_sig_m geschrieben oder man könnte auch sagen gesichert. Anschließend wird die Signalmenge sig_m gesetzt. Beispielsweise......

    sigprocmask(SIG_BLOCK, &neue_signal_maske, &backup_signal_maske);
    /*...viele Zeilen Code später wollen
         wir die alte Signalmaske wiederherstellen....*/
    sigprocmask(SIG_SETMASK, &backup_signal_maske, NULL);  


Folgende drei 'wie' Konstanten stehen in dabei zur Verfügung....

  • SIG_BLOCK
    Signalmenge bekommt alle in sig_m stehenden Signale hinzugefügt.
  • SIG_UNBLOCK
    Die in sig_m stehenden Signale werden alle entfernt.
  • SIG_SETMASK
    Eine neue Signalmaske wird komplett neu erstellt mit den Signale die sich in sig_m befinden.

Wollen sie die Signalmaske ändern, oder keine Signale während eines bestimmten Codeabschnittes erlauben, gibt es dafür die Fuktion.....

#include <signal.h>

int sigsuspend(const sigset_t *sig_m);  

Mit dieser Funktion können sie einen Prozeß solang blockieren, bis ein Signal eintrifft. Und wer in sigsuspend parallelen zu der Funktion pause() zieht hat recht. Nur ist sigsuspend die zuverlässiger Alernative zu pause, da diese mit der Funktion sigprocmask zusammenhängt und eine einzige atomare Operation ist.

Bei Fehler geben übrigens alle Funktionen in diesem Kapitel -1 zurück.

Im nächsten Kapitel werden wir uns ein Beipiel zu diesen neuen Signalfunktionen ansehen.

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf