【问题标题】:Is it possible to ignore all signals?是否可以忽略所有信号?
【发布时间】:2012-04-06 17:26:44
【问题描述】:

我有一个服务器应用程序,我想保护它不被我可以忽略的任何信号停止。有没有办法一次忽略所有可能的信号,而不是一一设置?

【问题讨论】:

    标签: c unix signals


    【解决方案1】:

    是的:

    #include <signal.h>
    
    sigset_t mask;
    sigfillset(&mask);
    sigprocmask(SIG_SETMASK, &mask, NULL);
    

    这并不完全忽略信号,而是阻止它们;这在实践中是相同的效果。

    我想,SIGKILLSIGSTOP 是不能被屏蔽也不能以任何方式忽略的。

    如需更详细的语义,如掩码继承规则等,check the man page

    【讨论】:

    • 请不要忘记检查返回值。为简洁起见,我跳过了那部分。
    • ... 我想也不是 SIGABRT 或 SIGSEGV。
    • @KerrekSB:您实际上可以捕获 SIGSEGV 和 SIGBUS,所以我想您也可以忽略它们。当然,风险自负。 signal(7) 手册页只提到了 SIGSTOPSIGKILL
    • 你可以抓住他们,但你不能阻止他们。我想这与 SIGKILL 不同。
    • 来这里看看是否确实可以捕获/阻止 所有 信号,所以绝对值得一提的是 SIGSTOPSIGKILL 不能! :)
    【解决方案2】:

    阻止信号与忽略它们不同。

    当您按照 C2H5OH 的建议阻塞信号时,它会被添加到待处理的信号队列中,并在您解除阻塞后立即传递给进程。

    解锁可以使用

    #include <signal.h>
    
    sigset_t mask;
    sigemptyset(&mask);
    sigprocmask(SIG_SETMASK, &mask, NULL);
    

    要回答您关于如何忽略信号的问题,它必须由信号处理程序处理,这是一个用户定义的函数,每当信号传递到进程时就会执行

    static void foo (int bar)
    {
         /*some code here. In your case, nothing*/
    }
    

    然后使用

    注册这个函数
    signal(SIGINT,foo);   //or whatever signal you want to ignore
    

    如果你想忽略所有信号

    int i;
    for(i = 1; i <=31 ; i++)
    {
       signal(i,foo);
    }
    

    此代码将获取传递给进程的所有信号并忽略它们而不是阻塞它们。

    注意: 根据 man pages ,这不是推荐的方式,而是建议使用 sigaction 。请查看man sigaction

    【讨论】:

      【解决方案3】:

      基于sigprocmask()pthread_sigmask() 的解决方案对我不起作用。 这是我发现的工作:

      #include <signal.h>
      #include <unistd.h>
      #include <assert.h>
      int main() {
          struct sigaction act;
          act.sa_handler = SIG_IGN;
          for(int i = 1 ; i < 65 ; i++) {
              printf("i = %d\n", i);
              // 9 and 19 cannot be caught or ignored                                                                                                       
              // 32 and 33 do not exist                                                                                                                     
              if((i != SIGKILL) && (i != SIGSTOP) && (i != 32) && (i != 33)) {
                  assert(sigaction(i, &act, NULL) == 0);
              }
          }
          sleep(10000);
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-30
        • 1970-01-01
        • 2016-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多