【问题标题】:Handling multiple signals处理多个信号
【发布时间】:2011-12-01 15:03:37
【问题描述】:

我有一个关于处理信号的问题。 假设如果我们收到 SIGINT 信号,我们应该打印“Recieved Signal”。如果处理程序在十秒内收到另一个信号,它应该打印“Shutting Down”,然后以状态 1 退出。

我的代码是这样的:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void  handler(int);
void  secondhandler(int);
void  alrmhandler(int);

void alrmhandler (int alrmsig)
{  
  alarm(0);     
}

void secondhandler(int sig)
{
 /* after recieving second signal prints shutting down and exit */
 printf("Shutting Down\n");
 exit(1);
}

void handler ( int sig )  
{  
   /* recieve first SIGINT signal */
   printf ("Recieved Signal\n");
   /* handle for the alarm function */
   signal(SIGALRM, alrmhandler);
   /* start 10s alarm */
    alarm(10);
   /* catch second SIGINT signal within 10s*/
   signal(SIGINT, secondhandler);

 }



 int main( void )
 {
  signal(SIGINT, handler);
      printf( "Hello World!\n" );
  for ( ;; )
  {
    /* infinite loop */
  }

  return 0;
 }

我尝试用 dev c++ 编译它,但它失败了。因为 SIGALRM 未声明(在此函数中首次使用)。

无论如何,我想知道的是这段代码是否正确。我实际上有点不确定 alrmhandler()。我应该忽略 SIGALRM 吗?

【问题讨论】:

  • 将你的 for 循环内容更改为 sleep(1); 而不是将其留空,以便其他进程也有机会运行。

标签: c signal-handling


【解决方案1】:

如果您在 Windows 平台上,您将能够发送的唯一信号是:SIGABRT、SIGFPE、SIGILL、SIGINT、SIGSEGV 或 SIGTERM。

【讨论】:

  • 好的,谢谢。但是如果我在 linux 中运行它,它应该可以工作,不是吗?
  • @user1075627 :是的,编译应该在 linux 机器上运行,因为 SIGALRM 是在 signal.h 中定义的。
【解决方案2】:

你写:

我想知道的是这段代码是否正确。

不完全是。 printf() 不是async-signal-safe,因此不应从信号处理程序中调用,除非您非常确定这样做是安全的。在您提供的代码中这样做是安全的。

通常,alarm() 技术很容易竞争。您的 10 秒警报可能会在您的 secondhandler() 函数中间到期。为了防止这种情况,您可以屏蔽信号以使用a more sophisticated signal manipulation function 进行补偿。

有更优雅/灵活的方式来实现您想要的超时,但这可能是更适合codereview.stackexchange.com 的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多