Comment bloquer tous les SIGNAUX SANS fil à l'aide de SIGWAIT?
J'ai une application principale qui génère un sujet séparé pour traiter les messages d'une file d'attente. J'ai un problème sur AIX, quand j'appuie sur CTRL-C, il semble que certains de connexion "poignées" dans le fil de devenir invalide. J'ai un crochet d'arrêt dans le programme principal attraper le SIGINT mais sur AIX il semble en quelque sorte d'envoyer un signal sur le fil...mais ce n'est pas vraiment possible de ce que j'entends...
Essentiellement, je voudrais savoir si je veux le PRINCIPAL de l'application pour gérer TOUS les signaux, je suis intéressé et qui ont le thread/s ne JAMAIS manipuler tous les signaux...est qu'une "bonne pratique"?
Si oui, comment puis-je PAS utiliser "sigwait" dans le fil...en fait je ne veux pas de "code de signal" dans le thread/s...ils doivent tout simplement pas recevoir de signal du tout.
J'ai vidé tous les signaux:
sigemptyset(&set);
Et ont établi la SIG_BLOCK
s = pthread_sigmask(SIG_BLOCK, &set, NULL);
Donc, ici, est un mannequin d'essai gratuit:
#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();
}
Si je viens de créer un thread et ont, par exemple, le gestionnaire de signal SIGINT dans le thread PRINCIPAL, mais ne le font PAS a la SIG_BLOCK ensemble pour le thread et que l'utilisateur appuie sur CTRL-C....le fil affectée à tous, même si le gestionnaire de signal dans le thread principal d'exécution? Cela semble être ce que je vois sur AIX ;-(
Merci pour l'aide, beaucoup apprécié
Lynton
OriginalL'auteur Lynton Grice | 2011-11-11
Vous devez vous connecter pour publier un commentaire.
Avec
s = pthread_sigmask(SIG_BLOCK, &set, NULL);
, vous n'êtes pas bloque rien.Utilisation:
Si vous souhaitez bloquer tous les signaux, ou d'ajouter explicitement les signaux que vous souhaitez bloquer dans le
set
si vous utilisez SIG_BLOCK.Après avoir créé les threads, vous devez restaurer le masque de signal, sinon pas de fils va attraper n'importe quel signal.
Cependant, en regardant votre question précédente, il se peut que le fil d'attraper le signal ne supporte pas d'être interrompu. C'est, si vous êtes bloqué faire un syscall, et un signal arrive, que syscall obtient abandonnée. Certains systèmes d'exploitation par défaut pour appeler automatiquement le système d'appel encore une fois, certains renvoie une erreur et positionne errno à EINTR, dont l'application doit gérer et de mauvaises choses qui pourrait se passer si ce n'est pas traitée.
Au lieu de cela, installez votre les gestionnaires de signaux avec sigaction() à la place de signal() , et définir le
SA_RESTART
drapeau, ce qui va provoquer des appels système pour redémarrer automatiquement dans le cas où il a obtenu interrompu par un signal.Mise à jour de la réponse un peu.. Le masque de signal est les signaux qui ne peuvent pas être soulevées. Donc, si vous ne sigaddset(&ensemble, SIGINT); pthread_sigmask(SIG_BLOCK, &ensemble, NULL); , SIGINT sera défini dans la singnal masque, et cela signifie que le fil ne sera pas le recevoir. Si vous créez un nouveau thread, le thread hérite du signal de masque à partir du thread qui l'a créé.
Notez que si vous voulez un nouveau thread afin de commencer avec des signaux masqués (généralement nécessaire pour éviter les mauvaises conditions de course), vous devez bloquer les signaux avant d'appeler
pthread_create
, puis de restaurer le vieux masque de signal dans le thread d'origine aprèspthread_create
retourne.lorsque vous bloquez le signal et il est envoyé à il fil, le signal reste en attente sur le fil. Plus tard lorsque vous débloquer le fil, le signal est délivré. Si vous ne voulez pas le signal délivré, vous devez l'ignorer, de ne pas le bloquer.
OriginalL'auteur nos
Toujours mauvais design.
Ne pas utiliser CTRL+C pour arrêter une application d'une manière contrôlée.
Utiliser correctement conçu contrôleur de l'application qui sera accessible via CORBA, RMI, ou une autre méthode pour interagir avec l'utilisateur et le contrôle de l'arrière-plan de l'app.
Amusez-vous les gars...
OriginalL'auteur fjb_saper