Namensräume
Varianten
Aktionen

std::signal

Von cppreference.com
< cpp‎ | utility‎ | program
 
 
Dienstprogramm-Bibliotheken
Sprachunterstützung
Typunterstützung (Basistypen, RTTI)
Bibliotheks-Feature-Test-Makros (C++20)
Programm-Dienstprogramme
Variadische Funktionen
Coroutine-Unterstützung (C++20)
Vertragsunterstützung (C++26)
Drei-Wege-Vergleich
(C++20)
(C++20)(C++20)(C++20)  
(C++20)(C++20)(C++20)

Allgemeine Hilfsmittel
Relationale Operatoren (in C++20 veraltet)
 
 
Definiert in Header <csignal>
/* Signal-Handler */* signal( int sig, /* Signal-Handler */* handler );
(1)
extern "C" using /* Signal-Handler */ = void(int);
(2) (nur Exposition*)

Ändert die Behandlung des Signals sig. Abhängig von handler kann das Signal ignoriert, auf den Standardwert gesetzt oder von einer benutzerdefinierten Funktion behandelt werden.

Wenn der Signal-Handler auf eine Funktion gesetzt wird und ein Signal auftritt, ist es implementierungsabhängig, ob std::signal(sig, SIG_DFL) unmittelbar vor Beginn des Signal-Handlers ausgeführt wird. Außerdem kann die Implementierung einige implementierungsdefinierte Sätze von Signalen daran hindern, während der Ausführung des Signal-Handlers aufzutreten.

Für einige der Signale kann die Implementierung beim Programmstart std::signal(sig, SIG_IGN) aufrufen. Für den Rest muss die Implementierung std::signal(sig, SIG_DFL) aufrufen.

(Hinweis: POSIX hat sigaction eingeführt, um diese implementierungsabhängigen Verhaltensweisen zu standardisieren)

Inhalt

[edit] Parameter

sig - das Signal, für das der Signal-Handler gesetzt werden soll. Es kann ein implementierungsdefinierter Wert oder einer der folgenden Werte sein
definiert Signalarten
(Makrokonstante) [bearbeiten]
handler - der Signal-Handler. Dies muss einer der folgenden sein
  • SIG_DFL Makro. Der Signal-Handler wird auf den Standard-Signal-Handler gesetzt.
  • SIG_IGN Makro. Das Signal wird ignoriert.
  • Ein Zeiger auf eine Funktion. Die Signatur der Funktion muss äquivalent zu der folgenden sein
extern "C" void fun(int sig);


[edit] Rückgabewert

Vorheriger Signal-Handler bei Erfolg oder SIG_ERR bei Fehler (das Setzen eines Signal-Handlers kann auf einigen Implementierungen deaktiviert sein).

[edit] Signal-Handler

Die folgenden Einschränkungen gelten für die benutzerdefinierte Funktion, die als Signal-Handler installiert wird.

Wenn der Signal-Handler NICHT als Ergebnis von std::abort oder std::raise (asynchrones Signal) aufgerufen wird, ist das Verhalten undefiniert, wenn

  • der Signal-Handler eine Funktion in der Standardbibliothek aufruft, außer
  • std::abort
  • std::std::exit
  • std::quick_exit
  • std::signal mit dem ersten Argument als Nummer des aktuell behandelten Signals (ein asynchroner Handler kann sich selbst neu registrieren, aber keine anderen Signale).
  • der Signal-Handler auf ein Objekt mit statischer Speicherdauer zugreift, das kein std::atomic oder (seit C++11)volatile std::sig_atomic_t ist.
(bis C++17)

Ein einfacher sperrfreier atomarer Vorgang ist ein Aufruf einer Funktion f aus <atomic> oder <stdatomic.h>(seit C++23), so dass

  • f die Funktion std::atomic_is_lock_free ist,
  • f die Memberfunktion is_lock_free ist (z. B. std::atomic::is_lock_free()),
  • f eine nicht-statische Memberfunktion von std::atomic_flag ist,
  • f eine nicht-Memberfunktion ist und der erste Parameter von f den Typ cv std::atomic_flag* hat,
  • f eine nicht-statische Memberfunktion ist, die auf einem Objekt obj aufgerufen wird, so dass obj.is_lock_free() true zurückgibt, oder
  • f eine nicht-Memberfunktion ist und für jedes übergebene Pointer-to-Atomic-Argument arg zu f, std::atomic_is_lock_free(arg) true zurückgibt.

Das Verhalten ist undefiniert, wenn ein Signal-Handler eine der folgenden Aktionen ausführt:

  • Aufruf einer beliebigen Bibliotheksfunktion, außer einfachen sperrfreien atomaren Operationen und den folgenden *signal-sicheren* Funktionen (beachten Sie insbesondere, dass dynamische Speicherzuweisung nicht signal-sicher ist).
  • Zugriff auf ein Objekt mit Thread-Speicherdauer
  • ein dynamic_cast-Ausdruck
  • ein throw-Ausdruck
  • Eintritt in einen try-Block
  • Initialisierung einer statischen Variablen, die eine nicht-lokale dynamische Initialisierung durchführt (einschließlich verzögert bis zur ersten ODR-Verwendung).
  • Warten auf den Abschluss der Initialisierung einer beliebigen Variablen mit statischer Speicherdauer, da diese von einem anderen Thread gleichzeitig initialisiert wird.
(seit C++17)

Wenn die benutzerdefinierte Funktion bei der Behandlung von SIGFPE, SIGILL, SIGSEGV oder einem anderen implementierungsdefinierten Signal, das eine rechnerische Ausnahme spezifiziert, zurückkehrt, ist das Verhalten undefiniert.

Wenn der Signal-Handler als Ergebnis eines Aufrufs von std::abort oder std::raise (synchrones Signal) aufgerufen wird, ist das Verhalten undefiniert, wenn der Signal-Handler std::raise aufruft.

Beim Eintritt in den Signal-Handler ist der Zustand der Gleitkommaumgebung und die Werte aller Objekte undefiniert, außer

(seit C++11)

Beim Rückkehren aus einem Signal-Handler sind die Werte von Objekten, die vom Signal-Handler geändert wurden und keine volatile std::sig_atomic_t oder sperrfreien std::atomic-Typen sind, unbestimmt.

(bis C++14)

Ein Aufruf der Funktion signal() synchronisiert-mit jeder daraus resultierenden Ausführung des Signal-Handlers.

Wenn ein Signal-Handler als Ergebnis eines Aufrufs von std::raise (synchron) ausgeführt wird, dann ist die Ausführung des Handlers *sequenziert nach* dem Aufruf von std::raise und *sequenziert vor* dessen Rückkehr und läuft auf demselben Thread wie std::raise. Die Ausführung von Handlern für andere Signale ist *unsequenziert* im Verhältnis zum Rest des Programms und läuft auf einem nicht spezifizierten Thread.

Zwei Zugriffe auf dasselbe Objekt vom Typ volatile std::sig_atomic_t führen nicht zu einem Datenrennen, wenn beide im selben Thread auftreten, selbst wenn einer oder mehrere in einem Signal-Handler auftreten. Für jede Ausführung eines Signal-Handlers können die Auswertungen, die vom aufrufenden Thread durchgeführt werden, in zwei Gruppen A und B unterteilt werden, so dass keine Auswertungen in B *vor* Auswertungen in A geschehen, und die Auswertungen solcher volatile std::sig_atomic_t-Objekte Werte so erhalten, als ob alle Auswertungen in A *vor* der Ausführung des Signal-Handlers geschehen wären und die Ausführung des Signal-Handlers *vor* allen Auswertungen in B geschehen wäre.

(seit C++14)

[edit] Hinweise

POSIX verlangt, dass signal Thread-sicher ist, und spezifiziert eine Liste von asynchron-signal-sicheren Bibliotheksfunktionen, die von jedem Signal-Handler aufgerufen werden dürfen.

Signal-Handler sollen eine C-Verknüpfung haben und im Allgemeinen nur die Funktionen aus der gemeinsamen Teilmenge von C und C++ verwenden. Übliche Implementierungen erlauben jedoch die Verwendung einer Funktion mit C++-Verknüpfung als Signal-Handler.

[edit] Beispiel

#include <csignal>
#include <iostream>
 
namespace
{
    volatile std::sig_atomic_t gSignalStatus;
}
 
void signal_handler(int signal)
{
    gSignalStatus = signal;
}
 
int main()
{
    // Install a signal handler
    std::signal(SIGINT, signal_handler);
 
    std::cout << "SignalValue: " << gSignalStatus << '\n';
    std::cout << "Sending signal: " << SIGINT << '\n';
    std::raise(SIGINT);
    std::cout << "SignalValue: " << gSignalStatus << '\n';
}

Mögliche Ausgabe

SignalValue: 0
Sending signal: 2
SignalValue: 2

[edit] Referenzen

  • C++23 Standard (ISO/IEC 14882:2024)
  • 17.13.5 Signal-Handler [support.signal]
  • C++20 Standard (ISO/IEC 14882:2020)
  • 17.13.5 Signal-Handler [support.signal]
  • C++17 Standard (ISO/IEC 14882:2017)
  • 21.10.4 Signal-Handler [support.signal]

[edit] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 3756 C++17 es war unklar, ob std::atomic_flag signal-sicher ist sie ist

[edit] Siehe auch

führt den Signal-Handler für ein bestimmtes Signal aus
(funktion) [bearbeiten]
Fence zwischen einem Thread und einem Signal-Handler, der im selben Thread ausgeführt wird
(Funktion) [bearbeiten]
C-Dokumentation für signal