Signal
Un signal est un événement généré pour informer un processus ou un thread qu'une situation importante est arrivée. Lorsqu'un processus ou un thread a reçu un signal, le processus ou le thread arrêtera ce qu'il fait et prendra des mesures. Le signal peut être utile pour la communication inter-processus.
Signaux standard
Les signaux sont définis dans le fichier d'en-tête signal.H En tant que constante macro. Le nom du signal a commencé avec un «sig» et suivi d'une brève description du signal. Ainsi, chaque signal a une valeur numérique unique. Votre programme doit toujours utiliser le nom des signaux, pas le numéro de signaux. La raison en est que le numéro de signal peut différer en fonction du système mais la signification des noms sera standard.
La macro Nsig Le nombre total de signal est-il défini. La valeur de Nsig est un plus grand que le nombre total de signal défini (tous les nombres de signaux sont alloués consécutivement).
Voici les signaux standard:
Nom du signal | Description |
Faire un coup de pouce | Accrocher le processus. Le signal SIGHUP est utilisé pour signaler la déconnexion du terminal de l'utilisateur, peut-être parce qu'une connexion distante est perdue ou raccroche. |
Sigint | Interrompre le processus. Lorsque l'utilisateur tape le caractère INTR (normalement Ctrl + C), le signal SIGINT est envoyé. |
Sigquit | Quitter le processus. Lorsque l'utilisateur tape le caractère quitte (normalement Ctrl + \), le signal Sigquit est envoyé. |
Sigill | Instruction illégale. Lorsqu'une tentative est faite pour exécuter des ordures ou des instructions privilégiées, le signal Sigill est généré. De plus, Sigill peut être généré lorsque la pile déborde, ou lorsque le système a du mal à exécuter un gestionnaire de signaux. |
Sigtrap | Trace. Une instruction de point d'arrêt et d'autres instructions de trap générent le signal Sigtrap. Le débogueur utilise ce signal. |
Sigabrt | Avorter. Le signal Sigabrt est généré lorsque la fonction about () est appelée. Ce signal indique une erreur qui est détectée par le programme lui-même et rapporté par l'appel de fonction Abort (). |
Sigfpe | Exception à point flottante. Lorsqu'une erreur arithmétique mortelle s'est produite, le signal SigFPE est généré. |
Sigusr1 et Sigusr2 | Les signaux SIGUSR1 et SIGUSR2 peuvent être utilisés comme vous le souhaitez. Il est utile d'écrire un gestionnaire de signaux pour eux dans le programme qui reçoit le signal pour une communication interprète simple. |
Action par défaut des signaux
Chaque signal a une action par défaut, l'une des éléments suivants:
Terme: Le processus se terminera.
Cœur: Le processus se terminera et produira un fichier de vidage de base.
IGN: Le processus ignorera le signal.
Arrêt: Le processus s'arrêtera.
Cont: Le processus continuera d'être arrêté.
L'action par défaut peut être modifiée à l'aide de la fonction du gestionnaire. L'action par défaut d'un signal ne peut pas être modifiée. Sigkill et Sigabrt L'action par défaut du signal ne peut pas être modifiée ou ignorée.
Manipulation du signal
Si un processus reçoit un signal, le processus a un choix d'action pour ce type de signal. Le processus peut ignorer le signal, spécifier une fonction de gestionnaire ou accepter l'action par défaut pour ce type de signal.
Nous pouvons gérer le signal en utilisant signal ou sigaction fonction. Ici, nous voyons comment le plus simple signal() La fonction est utilisée pour gérer les signaux.
int signal () (int signum, void (* func) (int))Le signal() appellera le func fonction si le processus reçoit un signal signal. Le signal() Renvoie un pointeur pour fonctionner func En cas de succès ou il renvoie une erreur à Errno et -1 sinon.
Le func Le pointeur peut avoir trois valeurs:
Exemple de gestionnaire de signal de base
#inclureDans la capture d'écran de la sortie de l'exemple1.C, nous pouvons voir que dans la fonction principale, la boucle infinie s'exécute. Lorsque l'utilisateur a tapé Ctrl + C, l'arrêt d'exécution de la fonction principale et la fonction du gestionnaire du signal sont invoquées. Une fois la fonction de gestionnaire terminée, l'exécution de la fonction principale a repris. Lorsque le type d'utilisateur a tapé Ctrl + \, le processus est quitte.
Ignorer l'exemple des signaux
#inclureIci, la fonction du gestionnaire est de vous inscrire à Sig_ign () fonction pour ignorer l'action du signal. Donc, lorsque l'utilisateur a tapé Ctrl + C, Sigint Le signal génère mais l'action est ignorée.
Reriger l'exemple du gestionnaire de signaux
#inclureDans la capture d'écran de la sortie de l'exemple3.C, nous pouvons voir que lorsque l'utilisateur a tapé la première fois Ctrl + C, la fonction de gestionnaire a invoqué. Dans la fonction de gestionnaire, le gestionnaire de signaux s'inscrit pour Sig_dfl Pour l'action par défaut du signal. Lorsque l'utilisateur a tapé Ctrl + C pour la deuxième fois, le processus est terminé, ce qui est l'action par défaut de Sigint signal.
Signaux d'envoi:
Un processus peut également envoyer explicitement des signaux à lui-même ou à un autre processus. relevoir () et la fonction kill () peut être utilisée pour envoyer des signaux. Les deux fonctions sont déclarées dans le signal.Fichier d'en-tête H.
INT RAPING (INT SIGNUM)La fonction Raisier () utilisée pour l'envoi du signal signal au processus d'appel (lui-même). Il renvoie zéro en cas de succès et une valeur non nulle s'il échoue.
int kill (pid_t pid, int sigm)La fonction de mise à mort utilisée pour envoyer un signal signal à un groupe de processus ou de processus spécifié par piquer.
Exemple de gestionnaire de signaux SIGUSR1
#inclureIci, le processus envoie un signal SIGUSR1 à lui-même en utilisant la fonction Raisie ().
Programme de tueurs d'exemple de tue
#inclureIci, le processus envoie Sigusr1 signal à lui-même en utilisant tuer() fonction. getpid () est utilisé pour obtenir l'identifiant de processus de lui-même.
Dans l'exemple suivant, nous verrons comment les processus parents et enfants communiquent (communication inter-processus) en utilisant tuer() et fonction du signal.
Communication des enfants à l'enfant avec les signaux
#inclureIci, fourchette() La fonction crée un processus enfant et renvoie zéro au processus enfant et à un processus de processus enfant au processus parent. Ainsi, PID a été vérifié pour décider du processus parent et enfant. Dans le processus parent, il est dormi pendant 1 seconde afin que le processus d'enfant puisse enregistrer la fonction du gestionnaire de signaux et attendre le signal du parent. Après 1 seconde processus parent Envoyer Sigusr1 Signal au processus de l'enfant et attendre le signal de réponse de l'enfant. Dans le processus de l'enfant, il attend d'abord le signal du parent et lorsque le signal est reçu, la fonction de gestionnaire est invoquée. À partir de la fonction de gestionnaire, le processus de l'enfant en envoie un autre Sigusr1 signal au parent. Ici getppid () La fonction est utilisée pour obtenir l'ID de processus parent.
Conclusion
Le signal dans Linux est un grand sujet. Dans cet article, nous avons vu comment gérer le signal du très basique, et aussi comprendre comment le signal génère, comment un processus peut envoyer un signal à lui-même et un autre processus, comment le signal peut être utilisé pour la communication interprète.