GNU/Linux >> Tutoriels Linux >  >> Linux

Traitement du signal avec plusieurs threads sous Linux

pthreads(7) décrit que POSIX.1 requiert tous les threads dans les attributs de partage de processus, y compris :

  • signaler les dispositions

POSIX.1 exige également que certains attributs soient distincts pour chaque fil, y compris :

  • masque de signal (pthread_sigmask(3) )

  • pile de signaux alternative (sigaltstack(2) )

Le complete_signal du noyau Linux routine a le bloc de code suivant -- les commentaires sont très utiles :

/*
 * Now find a thread we can wake up to take the signal off the queue.
 *
 * If the main thread wants the signal, it gets first crack.
 * Probably the least surprising to the average bear.
 */
if (wants_signal(sig, p))
        t = p;
else if (!group || thread_group_empty(p))
        /*
         * There is just one thread and it does not need to be woken.
         * It will dequeue unblocked signals before it runs again.
         */
        return;
else {
        /*
         * Otherwise try to find a suitable thread.
         */
        t = signal->curr_target;
        while (!wants_signal(sig, t)) {
                t = next_thread(t);
                if (t == signal->curr_target)
                        /*
                         * No thread needs to be woken.
                         * Any eligible threads will see
                         * the signal in the queue soon.
                         */
                        return;
        }
        signal->curr_target = t;
}

/*
 * Found a killable thread.  If the signal will be fatal,
 * then start taking the whole group down immediately.
 */
if (sig_fatal(p, sig) &&
    !(signal->flags & SIGNAL_GROUP_EXIT) &&
    !sigismember(&t->real_blocked, sig) &&
    (sig == SIGKILL || !p->ptrace)) {
        /*
         * This signal will be fatal to the whole group.
         */

Donc, vous voyez que vous sont en charge de l'endroit où les signaux sont livrés :

Si votre processus a défini la disposition d'un signal sur SIG_IGN ou SIG_DFL , alors le signal est ignoré (ou par défaut -- kill, core ou ignore) pour tous les threads.

Si votre processus a défini la disposition d'un signal sur une routine de gestionnaire spécifique, vous pouvez contrôler quel thread recevra les signaux en manipulant des masques de signal de thread spécifiques à l'aide de pthread_sigmask(3) . Vous pouvez nommer un thread pour les gérer tous, ou créer un thread par signal, ou n'importe quel mélange de ces options pour des signaux spécifiques, ou vous fier au comportement par défaut actuel du noyau Linux de fournir le signal au thread principal.

Certains signaux sont cependant spéciaux selon le signal(7) page de manuel :

Un signal peut être généré (et donc en attente) pour un processus dans son ensemble (par exemple, lorsqu'il est envoyé à l'aide de kill(2)) ou pour un thread spécifique (par exemple, certains signaux, tels que SIGSEGV et SIGFPE, générés à la suite de l'exécution d'un des instructions spécifiques en langage machine sont dirigées vers les threads, tout comme les signaux destinés à un thread spécifique à l'aide de pthread_kill(3)). Un signal dirigé par le processus peut être délivré à n'importe lequel des threads qui n'a pas actuellement le signal bloqué. Si plus d'un des threads a le signal débloqué, alors le noyau choisit un thread arbitraire auquel délivrer le signal.


Ceci est légèrement nuancé, en fonction de la version du noyau Linux que vous utilisez.

En supposant que les threads posix 2.6, et si vous parlez du système d'exploitation envoyant SIGTERM ou SIGHUP, le signal est envoyé au processus, qui est reçu et géré par le thread racine. En utilisant les threads POSIX, vous pouvez également envoyer SIGTERM à des threads individuels, mais je suppose que vous demandez ce qui se passe lorsque le système d'exploitation envoie le signal au processus.

Dans 2.6, SIGTERM entraînera la sortie "propre" des threads enfants, alors qu'en 2.4, les threads enfants étaient laissés dans un état indéterminé.


Linux
  1. Envoyer des commandes à plusieurs sessions SSH avec Terminator

  2. Comment gérer plusieurs versions de Python avec Pyenv sous Linux

  3. Commande JQ sous Linux avec exemples

  4. Linux - La définition de l'affinité du processus en cours d'exécution avec l'ensemble de tâches échoue ?

  5. Les threads du noyau Linux sont-ils vraiment des processus du noyau ?

Installer Linux avec LVM

Remplacer du par de la poussière sous Linux

Commande Linux wc avec exemples

Commande Linux ip avec exemples

15 Commande Linux ps avec exemples

Comment gérer plusieurs versions de Java avec jEnv sous Linux