【问题标题】:using signal handler for ctrl-c - need help on infinite loops使用 ctrl-c 的信号处理程序 - 需要有关无限循环的帮助
【发布时间】:2012-04-20 08:37:03
【问题描述】:

我正在为 ctrl-c 信号使用信号处理程序。即每当生成 ctrl-c 信号而不是退出应用程序时,我都会执行一些操作。

让我们假设如果我的应用程序由于 while(1) 循环(任何错误情况)而挂起,我是否可以仅在这种情况下退出应用程序?

例如:

void handle()
{
    /*do some action*/
    ----
    ----
    ---

    if ( while(1) detected)
    {
    exit(0);
    }
}


main()
{
    struct sigaction myhandle; 
    myhandle.sa_handler = handle;
    sigemptyset(&myhandle.sa_mask);
    myhandle.sa_flags = 0;
    sigaction(SIGINT, &myhandle, NULL);

   while(1);
}

谢谢

【问题讨论】:

  • 1) 信号处理程序的声明/定义/签名错误,应该是void handle(int signum); 2: 查找man 2 siglongjmp

标签: c linux signals signal-handling


【解决方案1】:

在收到Ctrl-C 之类的信号之前,很难确定您的代码是否处于意外无限循环中。我可以建议一些启发式方法。有一个足够长的变量,最好是一个全局的unsigned long long int,并在你怀疑在循环的每次迭代中可能滑入无限循环的循环内不断增加这个变量。现在,当您接收到信号时,检查信号处理程序中此变量的值是否与阈值 MAX_NUMBER_OF_ITERATIONS 对照。如果变量超过用户定义的阈值,则声明一个无限循环并exit 否则继续。

这几行的东西-

#define MAX_NUMBER_OF_ITERATIONS 100000000

unsigned long long checkForEndlessLoop=0;
bool overflow;

void sigHandler (int signum)
{
   signal(sig, SIG_IGN); // Ignore it so that another Ctrl-C doesn't appear any soon
   if (overflow || (checkForEndlessLoop > MAX_NUMBER_OF_ITERATIONS) )
   {
      //Something's fishy in the loop.
      exit(0);
   }
   else
   {
      signal(SIGINT, sigHandler );
   }
}

int main ()
{
   signal(SIGINT, sigHandler );

   for (checkForEndlessLoop=0; SOME_SLOPPY_CONDITION; )
   {
      //Some processing here
      if (++checkForEndlessLoop == 0 )
          overflow=true;
   }

   checkForEndlessLoop=0;

   while (SOME_SLOPPY_CONDITION)
   {
      //Some processing here
      if (++checkForEndlessLoop == 0 )
          overflow=true;
   }

}

或者更简单的是,只要检测到错误情况,就使用SIG_IGNbreakSIGINT从错误循环中忽略,打印出错误消息并退出!

【讨论】:

  • 2) siglongjmp 3) 将条件变量声明为“volatile”以避免编译器缓存它的值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-20
  • 1970-01-01
相关资源
最近更新 更多