2014-12-01 9 views
5

Ich habe diesen Code, wo ich sigaddset und sigaction verwende. Allerdings, wenn ich das Ergebnis segaddset Kommentar ist die gleicheWozu wird sigaddset verwendet?

struct sigaction act; 

    act.sa_handler = process_alarm; 
    act.sa_flags = 0;   
    sigemptyset(&act.sa_mask); 
    //sigaddset(&act.sa_mask, SIGINT); 

    sigaction(SIGALRM, &act, NULL); 

    for(;;) 
    { 
     alarm(3); 
     pause(); 
    } 

Warum brauche ich es zu benutzen?

+1

haben Sie versucht, 'CTRL + C' zu drücken, wenn Sie Ihr Programm mit/ohne' sigaddset() 'ausführen? –

+0

@SouravGhosh ja aber wie in anderen Antworten gezeigt, ich die Alarm-Handler läuft, um schnell zu bemerken, seine Wirkung. Hinzufügen eines 'sleep (10)' in Handler und ich kann den Unterschied sehen :) – NeDark

Antwort

12

Sie 2 Dinge hier tun:

  1. ein sigset_t Bestücken. Ein Sigset_t ist nur eine Sammlung von Werten für Signale und wird in verschiedenen Systemaufrufen verwendet. Sie können:

    • Erstellen Sie eine leere sigset_t (sigemptyset()
    • ein Signal an den Satz hinzufügen (sigaddset())
    • ein Signal entfernen in dem Satz (sigdelset())
    • usw. ..
  2. Einstellung der Signalmaske für den Signalhandler.Sie tun das, indem Sie das sigset_t sa_mask Mitglied der struct sigaction manipulieren, wenn Sie einen Signalhandler mit einem Aufruf von sigaction() einrichten.

die Signalmaske einer Signalbehandlungsroutine bedeutet, dass, während die Signalbehandlungsroutine ausgeführt wird, die Signale, die in der Maske blockiert werden - das heißt die Signale werden nicht so lange behandelt werden, wie sie blockiert sind. Wenn der Signal-Handler beendet ist, werden die eingehenden Signale entsperrt. Ein Signal, das blockiert wird, ist nicht "verloren", es wird behandelt, wenn dieses bestimmte Signal wieder entsperrt wird.

Die sigaddset(&act.sa_mask, SIGINT); bedeutet, dass das Signal SIGINT nicht auftreten kann, während der Code für den Handler SIGALRM läuft.

Auf der anderen Seite, wenn Sie sigaddset(&act.sa_mask, SIGINT); kommentieren, haben Sie nur eine leere Liste von Signalen mit sigemptyset(&act.sa_mask); erstellt. Daher können alle Signale, die während der Ausführung der SIGALRM-Handlerfunktion auftreten, diesen Handler vorwegnehmen und den Signalhandler für dieses andere Signal ausführen. Für ein SIGINT würden Sie normalerweise keinen Unterschied zu manuellen Tests feststellen - es ist unwahrscheinlich, dass Sie STRG-C genau dann erreichen, wenn Ihr Handler für SIGALRM läuft und Ihr SIGALRM-Handler wahrscheinlich schnell genug läuft, dass Sie es nicht bemerken würden wenn das SIGINT etwas verspätet war.

0

sigaddset wird zum Hinzufügen der entsprechenden Signalmaske zu dieser Variable sigset_t verwendet.

In sigaction ist es nicht erforderlich. Sie können das verwenden, wenn Sie die sigprocmask verwenden, die das Signal blockieren soll, das wir in dieser Variable erwähnen.

5

Signale werden über den Typ sigset_t manipuliert. Mehr Operationen für Signale Sets verfügbar sind:

  • eine leere Menge S über sigemptyset schaffen, S = ∅
  • ein Signal S über sigaddset, S = {s} S∪
  • Entfernen zu einem Satz hinzuzufügen, S ein Signal s von einem Set über sigdelset, S = S \ {s}
  • erstellen Sie die Menge aller möglichen Signale über sigfillset.
  • Test ist ein Signal s ist in einem gegebenen Satz S über sigismember, s∈S?

Ein solcher Satz ist an verschiedenen Stellen verwendet: ein neues Verfahren Signalmaske einstellen, während Signalverarbeitung gesetzt zu blockieren, um den Satz von anstehenden Signale anfordert usw.

Wenn Sie verschiedene Signale fangen wollen, ist es may erscheint, dass einige Fangfunktionen nicht mit anderen unterbrochen werden dürfen. Sie können also eine Reihe von Signalen hinzufügen, die während der Übertragung eines bestimmten Signals blockiert werden sollen. Sie haben sich entschieden (wenn unkommentiert), SIGINT während der SIGALRM-Zustellung zu blockieren. Sie können dies nur beobachten, indem Sie während der Ausführung des Handlers ein SIGINT senden. was schwer zu realisieren ist.

Ein Beispiel, wo es wichtig sein kann?

Angenommen, der Handler von SIGUSR1 ändert eine gegebene Datenstruktur und der Handler für SIGUSR2 verwendet dieselbe Datenstruktur. Es ist sehr wichtig, dass beide Handler nicht gleichzeitig sind, einer kann nach dem anderen ausgeführt werden, aber Sie wollen wahrscheinlich nicht von einem während der Lieferung des anderen unterbrochen werden. Ihr Code ist self-concurrent, sagen, dass sogar im Falle von nur einem Thread, Signale können Sie zur Nebenläufigkeit führen.