scanf循环和信号处理程序

问题描述:

刚刚了解到sigacation,还实现了另一个计时器以使其更有趣。scanf循环和信号处理程序

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

volatile sig_atomic_t gotsignal; 


void handler(){ 

    gotsignal = 1; 

} 

int main(){ 

struct sigaction sig; 
struct itimerval timer; 

timer.it_value.tv_sec = 5; 
timer.it_value.tv_usec = 0; 
timer.it_interval = timer.it_value; 

sig.sa_handler = handler; 
sig.sa_flags = 0; 
sigemptyset(&sig.sa_mask); 

setitimer(ITIMER_REAL, &timer, 0); 
sigaction(SIGALRM, &sig, NULL); 


int value, y = 100, x=0; 

while(!gotsignal && x < y){ 
    printf("Insert a value: \n"); 
    scanf("%d", &value); 
    x+=value; 
    printf("Current x value: %d\n", x); 
} 
} 

我不明白的是,当它等待用户输入,我写5,但没有按回车。他仍然读它?他不应该清除它吗? 输出它给我:

Insert a value: 
1 
Current x value: 1 
Insert a value: 
2 
Current x value: 3 
Insert a value: 
5Current x value: 5 

我想会是这样:

Insert a value: 
1 
Current x value: 1 
Insert a value: 
2 
Current x value: 3 
Insert a value: 
5(Wthout pressing enter!)Current x value: 3 (He would forget about 5 no?) 

A(迂腐)正确signal处理程序可以做的非常几件事情:特别设置volatile sig_atomic_t变量(这是一些整数类型),也许呼吁siglongjmp [我甚至不知道siglongjmp]。

所以先申报

volatile sig_atomic_t gotsignal; 

那么你的信号处理仅仅是

void handler (void) 
{ 
    gotsignal = 1; 
} 

和你的循环是

while(!gotsignal && x < y){ 
    printf("Insert a value: \n"); 
    scanf("%d", &value); 
    x+=value; 
} 

不要忘了异步信号发生在任何时间(任何ma chine指令!!!),其中包括mallocprintf。切勿从处理程序中调用这些函数。

与信号处理不良相关的错误很难调试:它们是不可重现

考虑使用sigaction

+0

嗯。这就说得通了。但是如果我希望程序在信号之后停止等待scanf。例如,一旦他获得信号,他就会忘记他正在等待的scanf并正常重启循环。那可能吗? – JPS

+0

我认为'SIGALRM'信号将会停止'scanf',因为'read'系统调用(由'scanf'调用)会得到'EINTR'错误。您可能还想了解关于“select”,“pselect”或“poll”(或“ppoll”)系统调用的信息。您可以测试'scanf'是否因其返回值失败。 –

+0

+1也用于提示'sigaction',它与'signal'不同,完全符合POSIX。 – jweyrich