std::signal
| Défini dans l'en-tête <csignal>
|
||
/*signal-handler*/* signal( int sig, /*signal-handler*/* handler );
|
(1) | |
extern "C" using /*signal-handler*/ = void(int);
|
(2) | (exposition uniquement*) |
Modifie la gestion du signal sig. Selon la valeur de handler, le signal peut être ignoré, réglé par défaut, ou traité par une fonction définie par l'utilisateur invoquée comme (*handler)(sig).
Lorsque le gestionnaire de signal est défini sur une fonction et qu'un signal se produit, il est défini par l'implémentation si std::signal(sig, SIG_DFL) sera exécutée immédiatement avant le début du gestionnaire de signal. De plus, l'implémentation peut empêcher un ensemble défini par l'implémentation de signaux de se produire pendant l'exécution du gestionnaire de signal.
Pour certains signaux, l'implémentation peut appeler std::signal(sig, SIG_IGN) au démarrage du programme. Pour les autres, l'implémentation doit appeler std::signal(sig, SIG_DFL).
(Remarque : POSIX a introduit sigaction pour normaliser ces comportements définis par l'implémentation.)
Paramètres
| sig | - | le signal pour lequel définir le gestionnaire de signal. Il peut s'agir d'une valeur définie par l'implémentation ou de l'une des valeurs suivantes :
| ||||||
| gestionnaire | - | le gestionnaire de signal. Il doit s'agir de l'un des éléments suivants :
|
Valeur de retour
Gestionnaire de signal précédent en cas de succès ou SIG_ERR en cas d'échec (la configuration d'un gestionnaire de signal peut être désactivée sur certaines implémentations).
Gestionnaire de signal
Les limitations suivantes sont imposées à la fonction définie par l'utilisateur qui est installée comme gestionnaire de signal.
|
Si le gestionnaire de signal est appelé NON comme résultat de std::abort ou std::raise (signal asynchrone), le comportement est indéfini si
|
(jusqu'à C++17) |
|
Une opération atomique simple sans verrouillage est un appel d'une fonction f de <atomic> ou <stdatomic.h> (depuis C++23) , telle que :
Le comportement est indéfini si un gestionnaire de signal effectue l'une des actions suivantes :
|
(depuis C++17) |
Si la fonction définie par l'utilisateur retourne lors du traitement de SIGFPE , SIGILL , SIGSEGV ou tout autre signal défini par l'implémentation spécifiant une exception de calcul, le comportement est indéfini.
Si le gestionnaire de signal est appelé suite à std::abort ou std::raise (signal synchrone), le comportement est indéfini si le gestionnaire de signal appelle std::raise .
|
À l'entrée du gestionnaire de signal, l'état de l'environnement à virgule flottante et les valeurs de tous les objets sont non spécifiés, sauf pour
Au retour d'un gestionnaire de signal, la valeur de tout objet modifié par le gestionnaire de signal qui n'est pas volatile std:: sig_atomic_t ou std::atomic sans verrouillage est indéterminée. |
(jusqu'à C++14) | ||
|
Un appel à la fonction
Si un gestionnaire de signal est exécuté à la suite d'un appel à
std::raise
(de manière synchrone), alors l'exécution du gestionnaire est
séquencée-après
l'invocation de
Deux accès au même objet de type volatile std:: sig_atomic_t n'entraînent pas de course de données s'ils se produisent dans le même thread, même si un ou plusieurs se produisent dans un gestionnaire de signal. Pour chaque invocation de gestionnaire de signal, les évaluations effectuées par le thread invoquant un gestionnaire de signal peuvent être divisées en deux groupes A et B, de sorte qu'aucune évaluation dans B ne se produit-avant les évaluations dans A, et les évaluations de ces volatile std:: sig_atomic_t prennent des valeurs comme si toutes les évaluations dans A se produisaient-avant l'exécution du gestionnaire de signal et l'exécution du gestionnaire de signal se produisait-avant toutes les évaluations dans B. |
(depuis C++14) |
Notes
POSIX exige que signal soit thread-safe, et spécifie une liste de fonctions de bibliothèque sûres pour les signaux asynchrones pouvant être appelées depuis n’importe quel gestionnaire de signaux.
Les gestionnaires de signaux sont censés avoir une liaison C et, en général, utiliser uniquement les fonctionnalités du sous-ensemble commun du C et du C++. Cependant, les implémentations courantes permettent qu’une fonction avec une liaison C++ soit utilisée comme gestionnaire de signaux.
Exemple
#include <csignal> #include <iostream> namespace { volatile std::sig_atomic_t gSignalStatus; } void signal_handler(int signal) { gSignalStatus = signal; } int main() { // Installer un gestionnaire de signal std::signal(SIGINT, signal_handler); std::cout << "SignalValue: " << gSignalStatus << '\n'; std::cout << "Sending signal: " << SIGINT << '\n'; std::raise(SIGINT); std::cout << "SignalValue: " << gSignalStatus << '\n'; }
Sortie possible :
SignalValue: 0 Sending signal: 2 SignalValue: 2
Références
- Norme C++23 (ISO/CEI 14882:2024) :
-
- 17.13.5 Gestionnaires de signaux [support.signal]
- Norme C++20 (ISO/CEI 14882:2020) :
-
- 17.13.5 Gestionnaires de signaux [support.signal]
- Norme C++17 (ISO/IEC 14882:2017) :
-
- 21.10.4 Gestionnaires de signaux [support.signal]
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Applicable à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 3756 | C++17 | il n'était pas clair si std::atomic_flag est sûr pour les signaux | il l'est |
Voir aussi
|
exécute le gestionnaire de signal pour un signal particulier
(fonction) |
|
|
(C++11)
|
barrière entre un thread et un gestionnaire de signal exécuté dans le même thread
(fonction) |
|
Documentation C
pour
signal
|
|