GNU/Linux >> Tutoriels Linux >  >> Linux

Le signal peut-il être ignoré (perdu) ?

Mis à part le problème "trop ​​de signaux", les signaux peuvent être explicitement ignorés. A partir du man 2 signal :

If the signal signum is delivered to the process, then one of the
following happens:    
  *  If the disposition is set to SIG_IGN, then the signal is ignored.

Les signaux peuvent également être bloqués. À partir de man 7 signal;

A signal may be blocked, which means that it will not be delivered
until it is later unblocked.  Between the time when it is generated
and when it is delivered a signal is said to be pending.

Les ensembles de signaux bloqués et ignorés sont hérités par les processus enfants, il peut donc arriver que le processus parent de votre application ignore ou bloque l'un de ces signaux.

Que se passe-t-il lorsque plusieurs signaux sont délivrés avant que le processus n'ait fini de traiter les précédents ? Cela dépend du système d'exploitation. Le signal(2) la page de manuel liée ci-dessus en parle :

  • System V réinitialiserait la disposition du signal par défaut. Pire encore, la livraison rapide de plusieurs signaux entraînerait des appels récursifs (?).
  • BSD bloquerait automatiquement le signal jusqu'à ce que le gestionnaire ait terminé.
  • Sous Linux, cela dépend des indicateurs de compilation définis pour GNU libc , mais je m'attendrais au comportement de BSD.

Vous ne pouvez pas être sûr que chaque signal envoyé sera livré. Par exemple, le noyau Linux « fusionne » SIGCHLD si un processus prend beaucoup de temps à gérer SIGCHLD à partir d'un processus enfant quittant.

Pour répondre à une autre partie de votre question, les signaux sont "mis en file d'attente" dans le noyau si un certain nombre de signaux différents arrivent dans un intervalle trop court.

Vous devez utiliser sigaction() pour configurer le gestionnaire de signal avec le sa_sigaction membre de siginfo_t , en définissant le sa_mask membre des siginfo_t argumenter avec soin. Je pense que cela signifie masquer au moins tous les signaux "asynch". Selon la page de manuel pour Linux sigaction() , vous masquerez également le signal traité. Je pense que vous devriez définir le sa_flags membre à SA_SIGINFO, mais je ne me souviens pas pourquoi j'ai cette superstition. Je pense que cela donnera à votre processus un gestionnaire de signaux qui reste défini sans conditions de concurrence et qui ne sera pas interrompu par la plupart des autres signaux.

Écrivez votre fonction de gestionnaire de signal très, très soigneusement. Fondamentalement, définissez simplement une variable globale pour indiquer qu'un signal a été intercepté et que le reste du processus s'occupe de l'action souhaitée pour ce signal. Les signaux seront ainsi masqués le moins longtemps possible.

De plus, vous voudrez tester votre code de traitement du signal de manière très approfondie. Mettez-le dans un petit processus de test et envoyez autant de signaux SIGUSR1 et SIGUSR2 que possible, peut-être à partir de 2 ou 3 programmes d'envoi de signaux spéciaux. Mélangez également d'autres signaux, une fois que vous êtes sûr que votre code peut gérer SIGUSR1 et SIGUSR2 rapidement et correctement. Préparez-vous à un débogage difficile.

Si vous utilisez Linux et uniquement Linux, vous pourriez penser à utiliser signalfd() pour créer un descripteur de fichier que vous pouvez select() ou sondage pour recevoir ces signaux. Utilisation de signalfd() pourrait faciliter le débogage.


Un signal est garanti d'être livré, dans le sens où si un processus appelle avec succès kill , la cible recevra le signal. C'est asynchrone :l'expéditeur n'a aucun moyen de savoir quand le signal est reçu ou traité. Cependant, cela ne garantit pas que le signal sera délivré. La cible pourrait mourir avant d'avoir pu traiter le signal. Si la cible ignore le signal au moment où il est délivré, le signal n'aura aucun effet. Si la cible reçoit plusieurs instances du même numéro de signal avant de pouvoir les traiter, les signaux peuvent (et sont généralement) fusionnés :si vous envoyez deux fois le même signal à un processus, vous ne pouvez pas savoir si le processus recevra le signal. une fois ou deux. Les signaux sont principalement conçus pour tuer un processus ou pour attirer l'attention sur un processus, ils ne sont pas conçus pour la communication en tant que telle.

Si vous avez besoin d'une livraison fiable, vous avez besoin d'un mécanisme de communication différent. Il existe deux principaux mécanismes de communication entre les processus :un tube permet une communication unidirectionnelle; un socket permet une communication bidirectionnelle et plusieurs connexions au même serveur. Si vous avez besoin que la cible traite autant de notifications que vous l'envoyez, envoyez des octets via un canal.


Linux
  1. Linux installé sur un disque USB, les données peuvent-elles être perdues lors de l'arrêt ?

  2. Signaux Linux - Exemple de programme C pour capturer des signaux (SIGINT, SIGKILL, SIGSTOP, etc.)

  3. Fondamentaux des signaux Linux - Partie I

  4. Python - Piège tous les signaux

  5. Mise en file d'attente des signaux en C

13 façons d'aider Linux

IPC utilisant des signaux sur Linux

Quels numéros de signal fonctionnent avec la commande kill ?

',,' peut-il être associé à '..' ?

Comment puis-je surveiller le disque io ?

Qu'est-ce qui peut provoquer un signal 11 ?