c - 选择中断的系统调用

标签 c linux timer embedded-linux

我正在创建一个大约每秒运行一次的计时器,它正在等待按下一个键(我没有这样做)。当它运行时,它显示:

select : interrupted system call 
select : interrupted system call 
select : interrupted system call 
select : interrupted system call 

你能告诉我为什么会发生这种情况吗:

struct sigaction s1;
static timer_t tid3;    
sigfillset(&s1.sa_mask);
s1.sa_flags = SA_SIGINFO;
s1.sa_sigaction = SignalHandler;
if (sigaction(SIGU, &s1, NULL) == -1) 
{
  perror("s1 failed");
  exit( EXIT_FAILURE );
}
printf("\nTimer %d is setting up \n",TimerIdentity);    
tid3=SetTimer(SIGU, 1000, 1);

// ---------- SET timer values -------------------
static struct sigevent sigev;
static timer_t tid;
static struct itimerspec itval;
static struct itimerspec oitval;
sigev.sigev_notify = SIGEV_SIGNAL;
sigev.sigev_signo = signo;
sigev.sigev_value.sival_ptr = &tid;

if (timer_create(CLOCK_REALTIME, &sigev, &tid) == 0) 
{
    itval.it_value.tv_sec = sec/1000;
    itval.it_value.tv_nsec = (long)(sec % 1000) * (1000000L);
    //itval.it_value.tv_nsec = 0;

    if (mode == 1) 
    {
        itval.it_interval.tv_sec = itval.it_value.tv_sec;
        itval.it_interval.tv_nsec = itval.it_value.tv_nsec;
    }
    if (timer_settime(tid, 0, &itval, NULL) == 0) 
    {
        printf("Timer_settime \n");
    }
    else
    {
        perror("time_settime error!");
    }
}

//---------------- SIGNAL HANDLER ---------------- 

void SignalHandler(int signo, siginfo_t* info, void* context)
{
    else if (signo == SIGU) // for keypad being pressed
   {
      calltimer3function();
   }

}

//-----------------calltimer3function------------------------  

unsigned char key5_debounce=0,key5_debounce_count=0;
calltimer3function()
{
    if(!key5_debounce)
   {
       if((GPIORead(INPUT_SW5)==0))
       {
          key5_debounce=1;
       }
   }
   if(key5_debounce)
   {
       if((GPIORead(INPUT_SW5)==0))
       {
          key5_debounce_count++;
       }
       else
       key5_debounce=0;

        if(key5_debounce_count>=KEY_DEBOUNCE)
        {
           printf("key5 pressed\n");
           extr_count=1;
           printf("\nDisplay menu called");
           display_menu();

          key5_debounce=0;
          key5_debounce_count=0;
        }

   }
}

最佳答案

可能值得一提的是两件事:

  1. 诸如selectread等阻塞函数会被信号中断。您可能想在调用sigaction时设置SA_RESTART标志。 人信号(7):

If a signal handler is invoked while a system call or library function call is blocked, then either:

  • the call is automatically restarted after the signal handler returns; or
  • the call fails with the error EINTR.

Which of these two behaviors occurs depends on the interface and whether or not the signal handler was established using the SA_RESTART flag (see sigaction(2)). The details vary across UNIX systems; below, the details for Linux.

  • 在信号处理程序中,您应该只调用异步信号安全函数。或者使用the self-pipe trick完全避免在信号处理程序中执行任何操作。
  • 或者,有一种方法可以在不使用 timer_createtimerfd_create 的情况下使用计时器。 select 接受一个超时参数,该参数可用于指定下一次计时器到期之前的时间。然后,如果发生超时,select 将返回 0。此方法适用于其他事件解复用 API,例如 pollepoll

    关于c - 选择中断的系统调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35057264/

    相关文章:

    python - 如何保护 Python 源代码?

    c - 在没有整数的情况下重新启动c中的while循环

    PHP exec命令写入服务器

    linux - gawk 不会过滤掉更大的数字吗?

    java - 双(象棋)计时器

    objective-c - 定时? - cocoa

    c - 将定义传递给函数

    c - 指针NULL问题

    linux - ip 转发在 CentOS7 上的 netns 内不起作用

    Java swing 应用程序不工作