2017-07-20 23 views
0

Je sais que scanf attend l'entrée. Mais dans ce programme, j'ai écrit qu'il est en train d'imprimer bonjour dans une boucle infinie. Il n'attend pas que j'entre.Scanf n'attend pas l'entrée

#include <signal.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/time.h> 
#include<unistd.h> 

void timer_handler (int signum) 
{ 
static int count = 0; 
printf ("timer expired %d times\n", ++count); 
} 

int main() 
{ 
struct sigaction sa; 
struct itimerval timer; 


memset (&sa, 0, sizeof (sa)); 
sa.sa_handler = &timer_handler; 
sigaction (SIGALRM, &sa, NULL); 


timer.it_value.tv_sec = 0; 
timer.it_value.tv_usec = 250000; 
/* ... and every 250 msec after that. */ 
timer.it_interval.tv_sec = 1; 
timer.it_interval.tv_usec = 250000; 
/* Start a virtual timer. It counts down whenever this process is 
    executing. */ 
setitimer (ITIMER_REAL, &timer, NULL); 

/* Do busy work. 
*/ 
int i=0; 
while(1){ 
    scanf("%d",&i);  //****Not waiting for input**** 
    printf("hello"); 
} 
} 

Sortie:

 
timer expired 1 times 
hello timer expired 2 times 
hello timer expired 3 times 
hello timer expired 4 times 
hello timer expired 5 times 
hello timer expired 6 times 
hello timer expired 7 times 

Pourquoi?

?

+0

Utiliser 'scanf ("% d", &i);' au lieu de 'scanf ("% d", &i);' – rsp

+0

@rsp Même résultat. –

+1

@rsp Tous 'scanf()' 'spécificateurs, à l'exception c, n, [ 'L'espace suggéré dans' scanf ("% d", &i); 'sert peu de but – chux

Répondre

4

La fonction scanf sur les plateformes POSIX quelque part dans son implémentation utilise l'appel système read. Lorsque le signal de minuterie est en cours, l'appel read sera interrompu et retournera avec une erreur (EINTR), qui à son tour conduit à scanf retournant ainsi. Vous pouvez vérifier cela en vérifiant ce que scanfrenvoie. Dans ce cas, il doit renvoyer EOF avec errno toujours défini sur EINTR.

Une solution simple à ceci est de demander au signal redémarrer l'appel système interrompu. Cela se fait en ajoutant le membre du pavillon SA_RESTART dans les structures sigactionsa_flags:

sa.sa_flags = SA_RESTART; 

Plus d'informations peuvent être trouvées dans, par exemple this POSIX sigaction reference.

+0

crée-t-il un thread distinct pour gérer les signaux? –

+0

Qu'est-ce que" * it * "? Signaux * interruption * votre programme, ils n'ont rien à voir avec les threads –

+0

@AdityaJha Non, il n'y a pas de threads impliqués dans les signaux. –