Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> C Sprache

C++ Signalverarbeitung meistern: Sichere Interrupt-Verwaltung und saubere Programmausführung

Was sind Signale?

Signale sind Unterbrechungen, die vom Betriebssystem an einen Prozess gesendet werden und ein Programm vorzeitig beenden können. Sie können Interrupts erzeugen, indem Sie auf UNIX-, Linux-, macOS- oder Windows-Systemen Strg+C drücken.

Es gibt Signale, die ein Programm nicht abfangen kann, aber die folgende Liste zeigt Signale, die Sie in Ihrem Programm abfangen und darauf reagieren können. Diese Signale sind im C++-Header <csignal> definiert.

Nr. Signal & Beschreibung
1 SIGABRT – Anormale Beendigung des Programms, z. B. durch einen Aufruf von abort().
2 SIGFPE – Fehlerhafte arithmetische Operation, wie Division durch Null oder Überlauf.
3 SIGILL – Erkennung einer ungültigen Instruktion.
4 SIGINT – Empfang eines interaktiven Aufmerksamkeits-Signals (z. B. Strg+C).
5 SIGSEGV – Ungültiger Speicherzugriff (Segmentation Fault).
6 SIGTERM – Beendigungsanforderung, die an das Programm gesendet wird.

Die signal()-Funktion

Die C++-Signalbehandlungsbibliothek stellt die Funktion signal bereit, um unerwartete Ereignisse abzufangen. Die Syntax lautet:

void (*signal(int sig, void (*func)(int)))(int);

Vereinfacht nimmt diese Funktion zwei Argumente entgegen: das erste ist eine Ganzzahl für die Signalnummer, das zweite ein Zeiger auf die Signalbehandlungsfunktion.

Beispiel: SIGINT abfangen

Das folgende Programm registriert einen Handler für SIGINT und beendet sich sauber, wenn der Benutzer Strg+C drückt.

#include <iostream>
#include <csignal>
#include <unistd.h> // für sleep()

using namespace std;

void signalHandler(int signum) {
    cout << "Interrupt-Signal (" << signum << ") empfangen.\n";
    // Bereinigung und Ressourcenfreigabe hier
    exit(signum);
}

int main() {
    // SIGINT registrieren
    signal(SIGINT, signalHandler);

    while (true) {
        cout << "Gehe schlafen...." << endl;
        sleep(1);
    }
    return 0;
}

Ausgabe nach Drücken von Strg+C:

Gehe schlafen....
Gehe schlafen....
Gehe schlafen....
Interrupt-Signal (2) empfangen.

Die raise()-Funktion

Sie können Signale auch programmintern mit raise() erzeugen. Die Syntax:

int raise(int sig);

Der Parameter sig ist die Signalnummer (z. B. SIGINT, SIGABRT, SIGFPE, …).

Beispiel: Internes Auslösen von SIGINT

#include <iostream>
#include <csignal>
#include <unistd.h>

using namespace std;

void signalHandler(int signum) {
    cout << "Interrupt-Signal (" << signum << ") empfangen.\n";
    exit(signum);
}

int main() {
    int i = 0;
    signal(SIGINT, signalHandler);

    while (++i) {
        cout << "Gehe schlafen...." << endl;
        if (i == 3) {
            raise(SIGINT); // Signal selbst auslösen
        }
        sleep(1);
    }
    return 0;
}

Ausgabe:

Gehe schlafen....
Gehe schlafen....
Gehe schlafen....
Interrupt-Signal (2) empfangen.

Wichtige Hinweise

C Sprache

  1. C++-Datentypen verstehen: Grundlagen, Modifizierer und Best Practices
  2. C++-Operatoren meistern: Ein vollständiger Leitfaden mit praktischen Beispielen
  3. C++-Kommentare: Best Practices für lesbaren, wartbaren Code
  4. C++ Klassentemplates meistern: Ein praktischer Leitfaden
  5. C-Dateiverwaltung: I/O mit fopen, fprintf, fread & fseek meistern
  6. C++ Exception Handling meistern: Praktische try, catch, throw Beispiele
  7. Fehlerbehandlung in C meistern: Best Practices & Techniken
  8. C++ Programmiersprache: Überblick & Kernfeatures
  9. C++ Konstanten & Literale: Typen, Syntax & Best Practices
  10. C++ Operatoren: Typen, Nutzung & Best Practices