Quel est le lien entre SIGINT et les autres signaux de terminaison?

sur les systèmes POSIX, les signaux de terminaison ont généralement l'ordre suivant (selon de nombreuses pages de manuel et la spécification POSIX):

  1. SIGTERM - poliment demander un processus pour terminer. Il doit se terminer avec élégance, en nettoyant toutes les ressources (fichiers, sockets, processus enfants, etc.), la suppression des fichiers temporaires et ainsi de suite.

  2. SIGQUIT - plus énergique de la demande. Il doit mettre fin disgracieux, encore nettoyer des ressources qui ont absolument besoin de nettoyage, mais peut-être pas supprimer des fichiers temporaires, peut-être écrire des informations de débogage quelque part; sur certains systèmes aussi un dump core sera écrit (indépendamment du fait que le signal est saisi par l'application ou non).

  3. SIGKILL - plus énergique de la demande. On ne demande même pas au processus de faire quoi que ce soit, mais le système nettoiera le processus, qu'il le veuille ou non. Très probablement un dump de noyau est écrit.

comment SIGINT s'intègre-t-il dans cette image? Un processus CLI est habituellement terminé par SIGINT lorsque L'utilisateur tape CRTL+C, mais un processus de fond peut aussi être terminé par SIGINT en utilisant l'utilitaire KILL. Ce que je ne vois pas dans les spécifications ou les fichiers d'en-tête, c'est si SIGINT est plus ou moins fort que SIGTERM ou s'il y a une différence entre SIGINT et SIGTERM.

mise à jour:

Le meilleur la description des signaux de terminaison que j'ai trouvée jusqu'à présent se trouve dans la Documentation GNU LibC . Il explique très bien qu'il y a une différence voulue entre SIGTERM et SIGQUIT.

Il dit à propos de SIGTERM:

c'est la manière normale de demander poliment à un programme d'arrêter.

et il est dit à propos de SIGQUIT:

[...] et produit un noyau dump quand il termine le processus, tout comme un programme de signal d'erreur. Vous pouvez considérer cela comme une erreur de programme d'état "détecté" par l'utilisateur. [...] Certains types de nettoyage sont mieux omis dans la manipulation de SIGQUIT. Par exemple, si le programme crée des fichiers temporaires, il devrait traiter les autres demandes de résiliation en supprimant le temporaire fichier. Mais il est préférable pour SIGQUIT de ne pas les supprimer, de sorte que l'utilisateur peut les examiner dans en conjonction avec le vidage du cœur.

et SIGHUP est également assez bien expliqué. SIGHUP n'est pas vraiment un signal de terminaison, cela signifie simplement que la "connexion" à l'Utilisateur a été perdue, de sorte que l'application ne peut pas s'attendre à ce que l'utilisateur Lise une sortie supplémentaire (par exemple stdout/stderr output) et il n'y a plus d'entrée à attendre de l'utilisateur. Pour la plupart des applications qui signifie qu'ils feraient mieux d'arrêter. En théorie une application pourrait également décider qu'il va en mode démon quand un soupir est reçu et fonctionne maintenant comme un processus de fond, l'écriture la sortie vers un fichier journal configuré. Pour la plupart des démons déjà en arrière-plan, SIGHUP signifie généralement qu'ils vont réexaminer leurs fichiers de configuration, donc vous les envoyez aux processus en arrière-plan après avoir édité les fichiers de configuration.

cependant, il n'y a pas d'explication utile de SIGINT sur cette page, si ce n'est qu'elle est envoyée par CRTL+C. y a-t-il une raison pour laquelle on traiterait SIGINT d'une manière différente de SIGTERM? Si oui, pour quelle raison serait-ce et comment la manipulation être différents?

83
demandé sur Mecki 2010-10-28 14:59:31

6 réponses

SIGTERM et SIGKILL sont prévus pour les requêtes générales "terminer ce processus". SIGTERM (par défaut) et SIGKILL (toujours) provoqueront la fin du processus. SIGTERM peut être attrapé par le processus (par exemple pour qu'il puisse faire son propre nettoyage s'il le veut), ou même ignoré complètement; mais SIGKILL ne peut pas être attrapé ou ignoré.

SIGINT et SIGQUIT sont spécifiquement destinés aux requêtes du terminal: des caractères d'entrée particuliers peuvent être assignés à générez ces signaux (en fonction des paramètres de contrôle du terminal). L'action par défaut pour SIGINT est le même type de fin de processus que L'action par défaut pour SIGTERM et l'action immuable pour SIGKILL; L'action par défaut pour SIGQUIT est aussi la fin de processus, mais des actions supplémentaires définies par l'implémentation peuvent se produire, telles que la génération d'un dump de noyau. Soit peut être pris ou ignorés par le processus si nécessaire.

SIGHUP, comme vous dites, est destiné à indiquer que le raccordement terminal a été perdu, plutôt que d'être un signal de raccordement en tant que tel. Mais, encore une fois, l'action par défaut pour SIGHUP (si le processus ne le rattrape pas ou ne l'ignore pas) est de terminer le processus de la même manière que SIGTERM etc. .

il y a un tableau dans le POSIX definitions for signal.h qui liste les différents signaux et leurs actions et buts par défaut, et le General Terminal Interface chapitre comprend beaucoup plus de détails sur les signaux liés au terminal.

64
répondu Matthew Slattery 2010-10-28 23:35:03

comme DarkDust a noté que de nombreux signaux ont les mêmes résultats, mais les processus peuvent y attacher des actions différentes en distinguant comment chaque signal est généré. En regardant le code source du noyau FreeBSD (kern_sig.c) je vois que les deux signaux sont traités de la même manière, ils terminer le processus et sont livrés à n'importe quel thread.

SA_KILL|SA_PROC,             /* SIGINT */
SA_KILL|SA_PROC,             /* SIGTERM */
8
répondu Diomidis Spinellis 2010-10-28 15:49:55

après une recherche rapide sur Google pour sigint vs sigterm , il semble que la seule différence voulue entre les deux soit si elle a été initiée par un raccourci clavier ou par un appel explicite à kill .

en conséquence, vous pouvez, par exemple, intercepter sigint et faire quelque chose de spécial avec elle, sachant qu'il a probablement été envoyé par un raccourci clavier. Peut-être rafraîchir l'écran ou quelque chose, au lieu de mourir (pas recommandé, car les gens attendez-vous à ce que ^C tue le programme, juste un exemple).

j'ai également appris que ^\ devrait envoyer sigquit, que je peux commencer à utiliser moi-même. Semble très utile.

7
répondu Jonathan 2010-10-29 13:39:08

certaines sont ANSI C et d'autres pas

une différence considérable est que:

  • SIGINT et SIGTERM sont ANSI C, donc plus portable
  • SIGQUIT et SIGKILL ne sont pas

ils sont décrits à la section "7.14 manipulation des signaux "du C99 projet N1256 :

  • SIGINT reception of an interactive signal d'attention
  • SIGTERM une demande de résiliation envoyé pour le programme

ce qui fait de SIGINT un bon candidat pour un Ctrl interactif + C.

4

en utilisant kill (à la fois l'appel système et l'utilitaire` vous pouvez envoyer presque n'importe quel signal à n'importe quel processus, étant donné que vous avez la permission. Un processus ne peut pas distinguer comment un signal a pris vie et qui l'a envoyé.

cela étant dit, SIGINT est vraiment destiné à chanter l'interruption Ctrl-C, alors que SIGTERM est le signal terminal général. Il n'y a pas de concept de signal "plus fort", à la seule exception qu'il y a des signaux qui ne peuvent pas être Bloqué ou manipulé (SIGKILL et SIGSTOP, selon la page de manuel).

un signal ne peut être que" plus puissant " qu'un autre signal en ce qui concerne la façon dont un processus de réception traite le signal (et quelle est l'action par défaut pour ce signal). Par exemple, par défaut, SIGTERM et SIGINT mènent à la fin. Mais si vous ignorez SIGTERM alors il ne mettra pas fin à votre processus, alors que SIGINT le fait encore.

3
répondu DarkDust 2010-10-28 11:23:19

à l'exception de quelques signaux, les manipulateurs de signaux peuvent capter les différents signaux, ou le comportement par défaut à la réception d'un signal peut être modifié. Voir la page de manuel signal(7) pour plus de détails.

0
répondu Ignacio Vazquez-Abrams 2010-10-28 11:20:45