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 */
}