GNU/Linux >> Tutoriels Linux >  >> Linux

Quel thread gère le signal ?

Lisez attentivement signal(7) &pthread(7) &pthread_kill(3) &sigprocmask(2) &pthread_sigmask(3) - que vous pourriez utiliser (pour bloquer SIGINT dans les threads indésirables). Lisez aussi un tutoriel pthread.

Évitez d'utiliser des signaux pour communiquer ou synchroniser entre les threads. Considérez par ex. mutex (pthread_mutex_lock etc...) et variables de condition (pthread_cond_wait etc...).

Si l'un des threads exécute une boucle d'événement (par exemple autour de poll(2)...), envisagez d'utiliser signalfd(2).


Si vous envoyez un signal à un processus, quel thread du processus gérera ce signal est indéterminé.

Selon pthread(7) :

POSIX.1 exige également que les threads partagent une gamme d'autres attributs (c'est-à-dire que ces attributs sont à l'échelle du processus plutôt que par thread):
...
- disposition des signaux
...

POSIX.1 distingue les notions de signaux dirigés vers le processus dans son ensemble et de signaux dirigés vers des threads individuels. Selon POSIX.1, un signal dirigé par un processus (envoyé en utilisant kill(2) , par exemple) doit être géré par un seul, arbitrairement thread sélectionné dans le processus.

Si vous souhaitez qu'un thread dédié dans votre processus traite certains signaux, voici un exemple de pthread_sigmask(3) vous montre comment faire :

Le programme ci-dessous bloque certains signaux dans le thread principal, puis crée un thread dédié pour récupérer ces signaux via sigwait(3). La session shell suivante illustre son utilisation :

$ ./a.out &
[1] 5423
$ kill -QUIT %1
Signal handling thread got signal 3
$ kill -USR1 %1
Signal handling thread got signal 10
$ kill -TERM %1
[1]+  Terminated              ./a.out

Origine du programme

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

/* Simple error handling functions */

#define handle_error_en(en, msg) \
        do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

static void *
sig_thread(void *arg)
{
    sigset_t *set = arg;
    int s, sig;

   for (;;) {
        s = sigwait(set, &sig);
        if (s != 0)
            handle_error_en(s, "sigwait");
        printf("Signal handling thread got signal %d\n", sig);
    }
}

int
main(int argc, char *argv[])
{
    pthread_t thread;
    sigset_t set;
    int s;

   /* Block SIGQUIT and SIGUSR1; other threads created by main()
       will inherit a copy of the signal mask. */

   sigemptyset(&set);
    sigaddset(&set, SIGQUIT);
    sigaddset(&set, SIGUSR1);
    s = pthread_sigmask(SIG_BLOCK, &set, NULL);
    if (s != 0)
        handle_error_en(s, "pthread_sigmask");

   s = pthread_create(&thread, NULL, &sig_thread, (void *) &set);
    if (s != 0)
        handle_error_en(s, "pthread_create");

   /* Main thread carries on to create other threads and/or do
       other work */

   pause();            /* Dummy pause so we can test program */
}

Linux
  1. Quelle commande de terminal Linux utilisez-vous le plus ?

  2. Alternative à "dd" qui ne tronque pas le fichier ?

  3. Linux - Comment déterminer quel module corrompt le noyau ?

  4. Quel système de fichiers à sauvegarder est le meilleur ? ?

  5. Comment définir le nom d'un thread dans les pthreads Linux ?

Comment le noyau Linux gère les interruptions

Quelle distribution Linux est la meilleure pour la confidentialité ?

Comment utiliser la commande which sous Linux

Quelle priorité en temps réel est la priorité la plus élevée sous Linux

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

Pourquoi est-il possible de retourner l'écran ?