C 选择中断系统调用

C 选择中断系统调用,c,linux,timer,embedded-linux,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; sigfil

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

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();
   }
}


也许值得一提的是两件事:

  • 阻塞功能,如
    选择
    读取
    等。。被信号打断。调用
    sigaction
    时,您可能需要设置
    SA_RESTART
    标志<代码>人工信号(7):
  • 如果在系统调用或库函数调用被阻止时调用信号处理程序,则:

    • 信号处理程序返回后,调用自动重启;或
    • 调用失败,错误为EINTR
    这两种行为中的哪一种发生取决于接口以及信号处理程序是否是使用SA_重新启动标志建立的(请参阅sigaction(2))。UNIX系统的细节各不相同;下面是Linux的详细信息

  • 在信号处理程序中,您应该只调用异步信号安全函数。或用于避免在信号处理程序中执行任何操作

  • 或者,有一种方法可以使计时器不使用
    timer\u create
    timerfd\u create
    <代码>选择接受超时参数,该参数可用于指定下一个计时器到期前的时间。然后,
    select
    如果发生超时,则返回0。此方法适用于其他事件解复用API,例如
    poll
    epoll

    非常烦人。。什么烦人?按下按钮的用户体验?弹出的消息信号:中断系统调用,我现在不按任何按钮其空处理程序请显示一个。您甚至还没有显示
    sigev
    的声明和设置,以及
    select
    调用的方式/位置。这与您的问题高度相关。在代码中,我没有使用任何printf或任何其他同步信号,它只是空的处理程序,甚至没有perror(select)或somthing@vm1991您需要发布一个完整的示例,我们可以运行并查看您看到的内容。代码是项目的一小部分,此计时器仅使用上述代码。正如您在处理程序中看到的,此计时器无法访问其他代码。它仅调用calltimer3function()@vm1991可能您是对的,但是如果没有源代码,我们将永远无法确定。@maxim hey thanx对于您目前的回答,我想SIGFILLSET会有问题吗?我应该在sigfill之前使用SIGEPTYSET insted还是SIGEPTY?它会提供一些区别吗??
    //-----------------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;
            }
    
       }
    }