GNU/Linux >> Linux Esercitazione >  >> Linux

Quale thread gestisce il segnale?

Leggi attentamente signal(7) &pthread(7) &pthread_kill(3) &sigprocmask(2) &pthread_sigmask(3) -che potresti usare (per bloccare SIGINT in thread indesiderati). Leggi anche un tutorial su pthread.

Evita di usare segnali per comunicare o sincronizzare tra thread. Considera ad es. mutex (pthread_mutex_lock ecc...) e variabili di condizione (pthread_cond_wait ecc...).

Se uno dei thread esegue un ciclo di eventi (ad es. attorno a poll(2)...) considera l'utilizzo di signalfd(2).


Se invii un segnale a un processo, quale thread nel processo gestirà questo segnale è indeterminato.

Secondo pthread(7) :

POSIX.1 richiede inoltre che i thread condividano una gamma di altri attributi (ovvero, questi attributi sono a livello di processo anziché per thread):
...
- disposizioni segnaletiche
...

POSIX.1 distingue le nozioni di segnali diretti al processo nel suo insieme e segnali diretti a singoli thread. Secondo POSIX.1, un segnale diretto dal processo (inviato usando kill(2) , ad esempio) dovrebbero essere gestite da un singolo, arbitrariamente thread selezionato all'interno del processo.

Se vuoi che un thread dedicato nel tuo processo gestisca alcuni segnali, ecco un esempio da pthread_sigmask(3) ti mostra come farlo:

Il programma seguente blocca alcuni segnali nel thread principale, quindi crea un thread dedicato per recuperare quei segnali tramite sigwait(3). La seguente sessione di shell ne dimostra l'uso:

$ ./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

Fonte del programma

#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. Come segnalare la fine dell'ingresso Stdin?

  2. La differenza tra individuare/dov'è/quale?

  3. Come impostare il nome di un thread nei pthread di Linux?

  4. Tracciare le origini del segnale UNIX?

  5. Gestione del segnale con più thread in Linux

Come il kernel Linux gestisce gli interrupt

Quale distribuzione Linux è la migliore per la privacy?

Come utilizzare il comando which in Linux

Quale priorità in tempo reale è la priorità più alta in Linux

Quali numeri di segnale funzionano con il comando kill?

Perché è possibile capovolgere lo schermo?