Ho un'applicazione principale che genera un thread separato per elaborare i messaggi da una coda. Ho un problema su AIX quando premo CTRL-C poiché sembra che alcuni "handle di connessione" nel thread non siano più validi. Ho un hook di shutdown nel programma principale che cattura SIGINT ma su AIX sembra in qualche modo inviare un segnale anche al thread ... anche se questo non è realmente possibile da quello che sento ...Come bloccare tutti i SEGNALI nel thread SENZA usare SIGWAIT?
Essenzialmente I vorrei sapere se voglio che l'applicazione MAIN gestisca TUTTI i segnali a cui sono interessato e che il thread/i non gestisca MAI alcun segnale ... è questa "buona pratica"?
Se è così, come NON posso usare "sigwait" nel thread ... infatti non voglio alcun "codice segnale" nel thread/s ... essi semplicemente non devono ricevere alcun segnale.
ho svuotato tutti i segnali:
sigemptyset(&set);
E ho posto il SIG_BLOCK
s = pthread_sigmask(SIG_BLOCK, &set, NULL);
ecco un manichino di programmi di prova:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#define handle_error_en(en, msg) do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
static void * threadMainLoop(){
//Here I do not want the thread to use "sigwait"....
while(running == TRUE){
//do some thread work and never have any signals come in
}
}
void shutdownHook(int sig){
printf("\nCtrl-C pressed....shutdown hook in main...\n");
}
void signalErrorHandler(int signum){
printf("\nSignal error handler in main...\n");
}
int main(int argc, char *argv[]){
pthread_t thread;
sigset_t set;
int s;
//Catch the following signals in the MAIN thread
(void) signal(SIGINT, shutdownHook);
(void) signal(SIGSEGV, signalErrorHandler);
(void) signal(SIGBUS, signalErrorHandler);
(void) signal(SIGILL, signalErrorHandler);
(void) signal(SIGTERM, signalErrorHandler);
(void) signal(SIGABRT, signalErrorHandler);
sigemptyset(&set); //BLOCK all signals
s = pthread_sigmask(SIG_BLOCK, &set, NULL);
if (s != 0)
handle_error_en(s, "pthread_sigmask");
s = pthread_create(&thread, NULL, &threadMainLoop, (void *) NULL);
if (s != 0)
handle_error_en(s, "pthread_create");
pause();
}
Se ho appena creo un thread e avere, ad esempio, il gestore del segnale SIGINT nel thread MAIN ma NON ha il set SIG_BLOCK per il thre annuncio e l'utente colpisce CTRL-C .... il thread viene influenzato del tutto anche se il gestore di segnale nel thread principale viene eseguito? Che sembra essere quello che sto vedendo in AIX ;-(
Grazie per l'aiuto, molto apprezzati
Lynton
Ciao, ma ho impostato "s = pthread_sigmask (SIG_BLOCK, & set, NULL);" e prova con CTRL-C che il thread non riceve il segnale? Ciò significa che lo sta bloccando? Se aggiungo "sigaddset (& set, SIGINT);" allora il filo riceve il segnale. Perdonami se sbaglio qui ... Sto ancora imparando .. ;-) Grazie per l'aiuto ;-) –
Aggiornamento della risposta un po '.. La maschera del segnale è i segnali che non possono essere sollevati. Quindi se si firma sigaddset (e set, SIGINT); pthread_sigmask (SIG_BLOCK, & set, NULL); , SIGINT verrà impostato nella maschera singnal e ciò significa che il thread non lo riceverà. Se si crea un nuovo thread, quel thread eredita la maschera del segnale dal thread che lo ha creato. – nos
Si noti che se si desidera un nuovo thread per iniziare con i segnali mascherato (di solito necessario per evitare condizioni di gara brutte) è necessario bloccare i segnali prima di chiamare 'pthread_create' e quindi ripristinare il vecchio maschera del segnale nel thread originale dopo' restituisce pthread_create' . –