问题
I know scanf waits for input. But in this program I have written it is printing hello in an infinite loop. Its not waiting for me to enter.
#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");
}
}
Output :
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
Why ?
?
回答1:
The scanf
function on POSIX platforms somewhere in its implementation is using the read
system call. When the timer signal is happening then the read
call will be interrupted and return with an error (EINTR
), which in turn leads to scanf
returning as well. You can check this by checking what scanf
returns. In this case it should return EOF
with errno
still set to EINTR
.
A simple solution to this is to ask the signal to restart the interrupted system call. This is done by adding the SA_RESTART
flag in the sigaction
structures sa_flags
member:
sa.sa_flags = SA_RESTART;
More information can be found in e.g. this POSIX sigaction reference.
来源:https://stackoverflow.com/questions/45212623/scanf-is-not-waiting-for-input