C-Standardbibliothek -<signal.h>
Einführung
<signal.h>Es ist eine Header-Datei in der C-Standardbibliothek, die zur Behandlung von Signalen verwendet wird.
signal.hDie Header-Datei definiert einen Variablentypsig_atomic_t, zwei Funktionsaufrufe und einige Makros zur Behandlung verschiedener Signale, die während der Programmausführung gemeldet werden.
Ein Signal ist ein asynchroner Benachrichtigungsmechanismus, der es einem Prozess ermöglicht, eine vordefinierte Handler-Funktion auszuführen, wenn ein bestimmtes Ereignis eintritt.
Nachfolgend ist ein einfaches Beispielprogramm, das zeigt, wie die Funktion signal verwendet wird, um das SIGINT-Signal abzufangen (normalerweise durch Strg+C erzeugt).
Beispiel
#include <signal.h>
#include <unistd.h>
// Globale Variable, die angibt, ob das Programm beendet werden soll
volatile sig_atomic_t stop = 0;
void handle_sigint(int sig) {
printf("Signal %d empfangen\n", sig);
stop = 1; // Exit-Flag setzen
}
int main() {
// Den Handler für das SIGINT-Signal auf die Funktion handle_sigint setzen
signal(SIGINT, handle_sigint);
while (!stop) { // Prüfen, ob beendet werden soll
printf("Läuft...\n");
sleep(1);
}
printf("Beende...\n");
return 0;
}
Im obigen Code fängt das Programm, wenn es läuft und der BenutzerCtrl+Cdrückt, das SIGINT-Signal ab und ruft die Funktion handle_sigint auf, wobei es die Signalnummer ausgibt.
Kompilieren und führen Sie den obigen Code aus; die Ausgabe ist wie folgt:
Running... Running... Running... ^CCaught signal 2 Exiting...
Codeanalyse:
volatile sig_atomic_t stop = 0;: eine globale Variable definierenstop, wird verwendet, um anzugeben, ob das Programm beendet werden soll. Mitvolatiledem Schlüsselwort wird sichergestellt, dass der Compiler Zugriffe auf diese Variable nicht wegoptimiert, da sie in einem Signalhandler geändert werden kann.sig_atomic_tDer Typ garantiert, dass Zugriffe auf diese Variable atomar sind.- In
handle_sigintIn der Signalhandler-Funktion setzen Siestopauf 1, was anzeigt, dass das Programm beendet werden soll. - Prüfen Sie in der Hauptschleife
stopden Wert der Variablen; wenn er auf 1 gesetzt ist, brechen Sie aus der Schleife aus und beenden Sie das Programm.
Bibliotheksvariablen
Die folgenden Variablentypen sind in der Header-Datei signal.h definiert:
| Laufende Nummer | Variablen & Beschreibung |
|---|---|
| 1 | sig_atomic_t Dies istintTyp, der als Variable in Signalhandlern verwendet wird. Es ist ein Ganzzahltyp eines Objekts, auf das auch bei asynchronen Signalen als atomare Entität zugegriffen werden kann. |
| 2 | sigset_t Ein Datentyp, der zur Darstellung einer Signalmenge verwendet wird. |
Bibliotheksmakros
<In der C-Standardbibliothek,SIG_Präfix-Makros undsignalWird zusammen mit Funktionen verwendet, um Signalverhalten zu definieren und zu behandeln. Die folgenden sind üblichSIG_Makros und ihre Verwendungen:
| Laufende Nummer | Makros & Beschreibung |
|---|---|
| 1 | SIG_DFL Stellt den Standard-Handler für ein Signal dar. Verwenden Sie dieses Makro, um ein Signal auf sein Standardverhalten zurückzusetzen. |
| 2 | SIG_ERR Stellt den Rückgabewert dar, wenn beim Festlegen einer Signal-Handler-Funktion ein Fehler auftritt. |
| 3 | SIG_IGN Signal ignorieren. |
Signaltypen:
| Konstanten | Beschreibung |
|---|---|
SIGABRT | vonabortDas von der Funktion erzeugte Signal, das eine abnormale Beendigung anzeigt |
SIGALRM | vonalarmDas von der Funktion festgelegte Signal für den Ablauf des Timers |
SIGBUS | Unzulässiger Speicherzugriff (zum Beispiel Zugriff auf eine nicht ausgerichtete Speicheradresse) |
SIGCHLD | Status des Kindprozesses hat sich geändert (beendet oder angehalten) |
SIGCONT | Fortsetzen der Ausführung eines angehaltenen Prozesses |
SIGFPE | Arithmetische Fehler (zum Beispiel Division durch Null, Gleitkomma-Ausnahmen) |
SIGHUP | Hangup-Signal (wird normalerweise verwendet, um eine Terminaltrennung zu erkennen) |
SIGILL | Unzulässiger Befehl |
SIGINT | Unterbrechungssignal (wird normalerweise durch Strg+C erzeugt) |
SIGKILL | Signal zur sofortigen Beendigung (kann nicht abgefangen oder ignoriert werden) |
SIGPIPE | Daten in eine Pipe schreiben, wenn kein lesender Prozess vorhanden ist |
SIGQUIT | Terminal-Quit-Signal (normalerweise durch Ctrl+\ erzeugt), erzeugt einen Core-Dump |
SIGSEGV | Segmentierungsfehler (unzulässiger Speicherzugriff) |
SIGSTOP | Stoppt die Prozessausführung (kann nicht abgefangen oder ignoriert werden) |
SIGTERM | Beendigungssignal |
SIGTSTP | Suspendiert den Prozess (normalerweise durch Ctrl+Z ausgelöst) |
SIGTTIN | Signal, das erzeugt wird, wenn ein Hintergrundprozess Daten vom Terminal liest |
SIGTTOU | Signal, das erzeugt wird, wenn ein Hintergrundprozess Daten auf das Terminal schreibt |
SIGUSR1 | Benutzerdefiniertes Signal 1 |
SIGUSR2 | Benutzerdefiniertes Signal 2 |
SIGPOLL | E/A-Ereignis (ersetzt SIGIO) |
SIGPROF | Signal bei Ablauf des Timers (durchsetitimerden gesetzten Profiling-Timer) |
SIGSYS | Illegaler Systemaufruf |
SIGTRAP | Breakpoint- oder Trap-Anweisung |
SIGURG | Signal für dringende Socket-Bedingung |
SIGVTALRM | Signal für Ablauf eines virtuellen Uhr-Timers |
SIGXCPU | CPU-Zeitlimit überschritten |
SIGXFSZ | Dateigrößenlimit überschritten |
Bibliotheksfunktionen
Die folgenden Funktionen sind in der Header-Datei signal.h definiert:
| Funktion | Beschreibung |
|---|---|
void (*signal(int sig, void (*func)(int)))(int); |
Signal-Handler festlegen. |
int raise(int sig); |
Ein Signal an den aktuellen Prozess senden. |
int kill(pid_t pid, int sig); |
Ein Signal an den angegebenen Prozess senden. |
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); |
Die blockierte Signalmenge prüfen oder ändern. |
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact); |
Den Signal-Handler prüfen oder ändern. |
int sigsuspend(const sigset_t *mask); |
Die aktuelle Signalmaske vorübergehend ersetzen und den Prozess anhalten, bis ein Signal abgefangen wird. |
int sigpending(sigset_t *set); |
Die Menge der ausstehenden Signale prüfen. |
int sigemptyset(sigset_t *set); |
Die Signalmenge auf die leere Menge initialisieren. |
int sigfillset(sigset_t *set); |
Die Signalmenge auf die vollständige Signalmenge initialisieren. |
int sigaddset(sigset_t *set, int signum); |
Das angegebene Signal zur Signalmenge hinzufügen. |
int sigdelset(sigset_t *set, int signum); |
Das angegebene Signal aus der Signalmenge entfernen. |
int sigismember(const sigset_t *set, int signum); |
Prüfen, ob das angegebene Signal in der Signalmenge enthalten ist. |
void abort(void); |
raiseSIGABRTDas Signal verursacht einen abnormalen Abbruch des Prozesses. |
unsigned int alarm(unsigned int seconds); |
Nach der angegebenen Anzahl von Sekunden sendenSIGALRMSignal an den aufrufenden Prozess. |
int pause(void); |
Den Prozess anhalten, bis ein Signal abgefangen wird. |
void psignal(int sig, const char *s); |
Signal-Beschreibungsinformationen ausgeben. |
char *strsignal(int sig); |
Die Zeichenkette mit der Signalbeschreibung zurückgeben. |
int sigwait(const sigset_t *set, int *sig); |
Blockieren, auf ein Signal warten und es behandeln. |