2017-09-26 5 views
0

Je veux travailler sur les gestionnaires de signaux dans le contexte de deux processus indépendants, à savoir l'auteur et le lecteur pour la notification. L'auteur envoie un premier signal SIGUSR1 au lecteur qui boucle jusqu'à ce qu'il entende le second signal SIGUSR2 de l'auteur.Gestionnaires de signaux imbriqués dans C

reader.c

static volatile sig_atomic_t done_waiting; 

int handler1(int signal){ 
    done_waiting = 0; 
    while(!done_waiting){ 
      (void)fprintf(stdout, " reader waiting for sigusr2: done_waiting = %d\n", done_waiting); 
    } 
(void)fprintf(stdout, " reader received sigusr2 \n); 
} 

int handler2 (int signal){ 
     done_waiting = 1; 
} 

main(){ 
    signal(SIGUSR1, handler1); 
    signal(SIGUSR2, handler2); 
    sleep(5); // sleep till we start worker 
} 

En writer.c, les signaux sont envoyés au lecteur comme

main(){ 
    kill(pid_reader, SIGUSR1); 
    sleep(5); 
    kill (pid_reader, SIGUSR2); 
} 

Lorsque j'exécute lecteur premier suivi par un travailleur, le programme se ferme à la boucle while. Et l'auteur écrit que "Aucun processus correspondant à vous n'a été trouvé".

Les gestionnaires de signaux d'imbrication sont-ils autorisés et si oui, est-ce recommandé? Aussi, existe-t-il un autre mécanisme alternatif pour que l'auteur informe le lecteur qu'il est prêt?

+1

Voir [Comment éviter d'utiliser 'printf()' dans les gestionnaires de signal?] (Http://stackoverflow.com/questions/16891019/how- to-avoid-using-printf-in-a-signal-handler /) pour des informations de base. Vous devriez faire le moins possible dans un gestionnaire de signal. Il existe des limites strictes sur les fonctions que vous pouvez appeler dans un signal plus court - et la famille de fonctions 'printf()' ne figure pas dans la liste des fonctions OK (ni si c'est utile, c'est 'strlen()' - mais sont de bonnes raisons pour 'printf()' et al et je ne suis pas au courant d'une bonne raison pour 'strlen()'). –

+1

Vous n'êtes pas en train d'imbriquer des gestionnaires de signaux, vous en avez installé deux pour des signaux différents. En outre, vous devriez regarder le 'sigsuspend (2)' et les appels connexes, qui permettent d'attendre un signal (plutôt que l'attente occupée que vous avez ici avec la boucle while). – bnaecker

Répondre

0

imbriqué peut-être signaux fait ce que vous vouliez dire, non imbriqués signauxmanutentionnaires? Pour clarifier, que se passera-t-il si un SIGUSR2 est reçu alors que le gestionnaire de SIGUSR1 est en cours d'exécution, c'est ce que vous voulez dire? Je suppose donc,

J'ai testé votre code, avec quelques modifications, pour obtenir le pid pour le processus de lecteur dans le processus d'écriture que j'ai utilisé les args à main.

Les résultats obtenus sont.

  1. Premier lecteur est calme
  2. Après avoir reçu SIGUSR1 il commence à écrire en continu qu'il attend SIGUSR2
  3. Lors de la réception SIGUSR2, il imprime « lecteur reçu SIGUSR2 »

Cela indique qu'il est possible d'avoir des signaux imbriqués. Cependant, je ne dirais pas qu'il est recommandé comme un design intentionnel. Comme mentionné dans les commentaires, vous devriez faire le moins possible dans les gestionnaires de signaux, certainement pas en boucle while. Et comme mentionné également dans les commentaires, faites très attention aux fonctions que vous appelez dans le contexte-signal, printf() n'est pas OK, même si cela peut sembler fonctionner correctement.

testé sur Linux, avec l'ancien noyau 3,16 et gcc 4.9