【问题标题】:stuck on scanf of fgets inside Signal handler function卡在信号处理函数中 fgets 的 scanf
【发布时间】:2013-03-13 07:02:59
【问题描述】:

我这样的程序信号处理程序?

sig_quit(int signo)
{
    //char ans[5];
    char ans;

                printf("Are you sure want to exit program ?Y/N \n");
                //while(check){ check = !scanf("%s", ans); }

                //scanf("%c",&ans);
                ans=getchar();
                    //fgets(ans,sizeof(ans),stdin);;
                    printf("ans is : %c",ans);           
                    if(ans=='y' ||  ans=='Y')
                    {                                   
                        printf("Goodbye\n");
                        exit(0);
                        return;
                    }
                    else if(ans!='y')
                    {   

                        printf("why ans is : %c",ans);

                    }   
}

好的默认行为是当你按下 ctrl+\ 问题问你“你确定要退出”吗? 如果用户按下'y',它将退出,但如果用户按下'y'以外的任何其他内容->它将再次停留在scanf,但我需要退出该功能并在用户按下后返回主怎么样?

简而言之:它卡住@ getchar()或scanf(),在插入除'y'之外的任何字符后再次卡住,提示它进行新输入,如果用户插入任何新字符它会卡住后退出信号处理函数回到main()

这是新版本的代码:

所以这是最近的代码:

volatile sig_atomic_t eflag = 0;
    int main(int argc, char *argv[])
    {

      /*Here are some code  ,,,,,, */

        Signal(SIGQUIT, sig_quit);  /* must call waitpid() */
         while (eflag) 
         {
            /* Main loop program code */

            log_msg(SIGQUIT);
         }



 ////// there is code below...
          .
          .
          .

    }
void log_msg(int signum)
{   
    char ans;
    //signal(SIGQUIT,SIG_IGN);  
            printf("Are you sure want to exit program ?Y/N \n");                        
        do  {
                ans=getchar();
                if(ans=='y' ||  ans=='Y')
                {                                   
                    printf("Goodbye\n");
                    exit(0);
                    return;
                }
                if(ans == 'n' || ans == 'N') return;

            }while(1);          
}


void
sig_quit(int signo)
{
    eflag = 1;
    /* Do some handling specific to SIGINT */
    log_msg(SIGQUIT);
}

如果用户按下“n||N”,getchar() 仍然会再次阻塞,直到他再次按下任何 char 并返回 main()。

【问题讨论】:

  • 这些函数在大多数信号处理程序中是不合法的;您正在调用 UB。

标签: c function signals printf scanf


【解决方案1】:

根据 C 标准,在信号处理程序中调用大多数库函数会导致未定义的行为。

实现可以提供额外的支持,但是如果你用一个也做 IO 的处理程序中断一个已经在做 IO 的函数,它很可能会导致不可预知的行为。

执行此操作的“正常”方法是让您的信号处理程序设置一个全局变量,并在 main 中进行测试以检查是否已设置,并采取适当的措施。

【讨论】:

    【解决方案2】:

    您希望我们阅读此代码吗?如果是这样,让它看起来像。否则,我们只会想“啊!那是阅读的负担。下一个!”...

    信号处理程序返回void。函数返回的类型应该总是在 C 中显式声明。由于ans 是为了存储getchar() 的返回值,所以它应该是int。

    void sig_quit(int sig) {
        int answer;
        do {
            puts("Are you sure you want to exit?");
            answer = getchar();
        } while (answer >= 0 && strchr("NnYy", answer) == NULL);
    
        if (strchr("Yy", answer)) { exit(0); }
    }
    

    “卡住”到底是什么意思?这并不完全清楚,但我认为您指的是 scanf 和 getchar 阻塞执行的行为;当程序无法立即使用数据时,它们将等待数据可用并同时阻止执行。您是否考虑过在用户在主线程中输入数据时运行后台线程以继续处理?

    【讨论】:

      【解决方案3】:

      将else 替换为

      if(ans == 'n' || ans == 'N') break;  
      

      编辑

      不知道有没有别的好办法:

      int main(){  
      char ans;  
      printf('wanna exit?');  
      do {  
      ans = getchar();  
      if(ans == 'y') exit(0);  
      if(ans == 'n') break;  
      }  
      while(1);  
      } 
      

      【讨论】:

      • 但是break需要循环,是否需要循环放? myHeader.h:290:34: 错误:break 语句不在循环或开关内
      • 好的,如果它不安全,如何制作这个场景?如果用户按下 SIGQUIT,即“ctrl+\”,确认问题将像任何传统程序一样出现,如果用户按下“y”,它将退出,但如果用户按下“n”,程序将恢复到信号之前的正常行为发生...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-07
      • 2017-09-25
      • 2019-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多