GNU/Linux >> Tutoriales Linux >  >> Linux

¿Qué hilo maneja la señal?

Lea atentamente signal(7) &pthread(7) &pthread_kill(3) &sigprocmask(2) &pthread_sigmask(3) -que podría usar (para bloquear SIGINT en hilos no deseados). Lea también un tutorial de pthread.

Evite el uso de señales para comunicarse o sincronizar entre subprocesos. Considere, por ejemplo, mutexes (pthread_mutex_lock, etc...) y variables de condición (pthread_cond_wait, etc...).

Si uno de los subprocesos ejecuta un bucle de eventos (por ejemplo, alrededor de poll(2)...) considere usar signalfd(2).


Si envía una señal a un proceso, no se determina qué subproceso del proceso manejará esta señal.

Según pthread(7) :

POSIX.1 también requiere que los subprocesos compartan una gama de otros atributos (es decir, estos atributos son para todo el proceso en lugar de por subproceso):
...
- disposiciones de la señal
...

POSIX.1 distingue las nociones de señales que se dirigen al proceso como un todo y señales que se dirigen a subprocesos individuales. De acuerdo con POSIX.1, una señal dirigida por proceso (enviada usando kill(2) , por ejemplo) debe ser manejado por un único, arbitrariamente hilo seleccionado dentro del proceso.

Si desea un hilo dedicado en su proceso para manejar algunas señales, aquí hay un ejemplo de pthread_sigmask(3) te muestra cómo hacerlo:

El programa a continuación bloquea algunas señales en el hilo principal y luego crea un hilo dedicado para obtener esas señales a través de sigwait (3). La siguiente sesión de shell demuestra su 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

Fuente del programa

#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. ¿Alternativa a 'dd' que no trunca el archivo?

  2. Linux:¿cómo determinar qué módulo contamina el kernel?

  3. ¿Cómo señalar el final de la entrada Stdin?

  4. La diferencia entre localizar/dónde está/cuál?

  5. ¿Cómo unirse a un hilo que está pendiente de bloquear IO?

Cómo el kernel de Linux maneja las interrupciones

¿Qué distribución de Linux es la mejor para la privacidad?

Cómo usar el comando which en Linux

¿Qué prioridad en tiempo real es la prioridad más alta en Linux?

¿Qué números de señal funcionan con el comando de matar?

¿Por qué es posible voltear la pantalla?