2011-08-16 11 views
1

J'essaie d'apprendre des signaux en utilisant la fonction de sigaction POSIX.apprentissage des signaux POSIX en utilisant sigaction

Ce que j'essaie de faire est d'inviter l'utilisateur pour l'entrée. Après l'invite, une alarme de 5 secondes est définie. Si l'utilisateur n'entre pas quelque chose avant que l'alarme n'expire, l'utilisateur est reprompté. Si l'utilisateur entre quelque chose, l'alarme est annulée et l'entrée est renvoyée. S'il n'y a pas d'entrée après la troisième ré-invite, le programme se termine.

Voici ce que j'ai jusqu'à présent. Ce que cela fait, après avoir affiché l'invite pour la première fois, lorsqu'aucune entrée n'est entrée, cela se termine par le message "Signal d'alarme".

#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <errno.h> 
#include <time.h> 
#include <signal.h> 

volatile sig_atomic_t count = 0; 

void sighandler(int signo) 
{ 
    ++count; 
} 

int main(void) 
{ 
    char buf[10]; 
    struct sigaction act; 
    act.sa_handler = sighandler; 

    sigemptyset(&act.sa_mask); 

    act.sa_flags = 0; 

    if(sigaction(SIGINT, &act, 0) == -1) 
    { 
    perror("sigaction"); 
    } 

    while(count < 3) 
    { 
    printf("Input please: "); 

    alarm(5); 

    if(fgets(buf, 10, stdin)) 
    { 
     alarm(0); 
     printf("%s", buf); 
    } 
    } 

return 0; 
} 
+3

Vous attrapez 'SIGINT', mais l'alarme utilise' SIGALRM'. – user786653

+0

Merci, utilisateur786653. – user695752

Répondre

3

Vous enregistrez votre gestionnaire pour SIGINT au lieu de SIGALRM. Ainsi, lorsque l'alarme arrive, elle n'est pas interceptée, par la disposition par défaut, le processus est terminé.

En note, vous pouvez également utiliser select pour cela.

+0

Et vous devriez utiliser 'select' pour cela, car cela évite la condition de concurrence (sinon inévitable) dans ce code. (Si le système est vraiment occupé, il faut donc plus de cinq secondes entre 'alarm (5)' et 'fgets', vous manquerez le signal et vous bloquerez dans' fgets' pour toujours.) – Nemo