【问题标题】:Scanf is not waiting for inputScanf 不等待输入
【发布时间】:2017-07-20 10:52:00
【问题描述】:

我知道 scanf 等待输入。 但是在我写的这个程序中,它正在打印 hello 在无限循环中。它不等我进入。

#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");   
}
}

输出:

计时器过期 1 次 你好计时器过期2次 你好计时器过期3次 你好计时器过期4次 你好计时器过期5次 你好计时器过期6次 你好计时器过期7次

为什么?

?

【问题讨论】:

  • 使用scanf(" %d",&amp;i); 而不是scanf("%d",&amp;i);
  • @rsp 结果相同。
  • @rsp 所有scanf() 说明符,除了c,n,[ 首先使用前导空白。 scanf(" %d",&amp;i); 中的建议空间用途不大。

标签: c timer signals posix


【解决方案1】:

POSIX 平台上的scanf 函数在其实现的某处使用read 系统调用。当计时器信号发生时,read 调用将中断并返回错误 (EINTR),这反过来又导致 scanf 也返回。您可以通过检查 scanf 返回 来检查这一点。在这种情况下,它应该返回EOF,而errno 仍设置为EINTR

一个简单的解决方案是要求信号重新启动被中断的系统调用。这是通过在sigaction 结构sa_flags 成员中添加SA_RESTART 标志来完成的:

sa.sa_flags = SA_RESTART;

更多信息可以在例如找到。 this POSIX sigaction reference.

【讨论】:

  • 什么是“”?信号中断你的程序,它们与线程无关。
猜你喜欢
  • 2013-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-22
  • 2015-04-12
  • 1970-01-01
  • 2012-01-17
相关资源
最近更新 更多