【问题标题】:sigprocmask doesn't restore my signal handlersigprocmask 不会恢复我的信号处理程序
【发布时间】:2015-07-13 03:25:57
【问题描述】:

我的代码 C Unix 有问题。我将复制关键部分: 因此,在第一个 sigprocmask 之后,我发送了一个信号,在 SIG_UNBLOCK 之后,之前的句柄(gestisciSignalDopoReg)不起作用,而是标准句柄管理我的信号,所以它只是终止了进程......出了什么问题?谢谢

struct sigaction gestoreSegnale;
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask,SIGTERM);
sigaddset(&mask,SIGINT);
sigaddset(&mask,SIGALRM);
sigaddset(&mask,SIGQUIT);
sigaddset(&mask,SIGHUP);
sigaddset(&mask,SIGSEGV);
sigaddset(&mask,SIGILL);
sigaddset(&mask,SIGPIPE);
void setSegnali(int segn,__sighandler_t handler){
  gestoreSegnale.sa_handler=handler;
  gestoreSegnale.sa_mask=mask;

  sigaction(segn, &gestoreSegnale, NULL);
}
void eseguiSetSegnali(__sighandler_t handler){
  setSegnali(SIGQUIT, handler);
  setSegnali(SIGSEGV, handler);
  setSegnali(SIGILL, handler);
  setSegnali(SIGHUP, handler);
  setSegnali(SIGTERM, handler);
  setSegnali(SIGINT, handler);
}
void main(){
 eseguiSetSegnali(gestisciSIGNALDopoReg);
 sigprocmask(SIG_BLOCK,&mask,NULL);
 .........other part of code......... 
 sigprocmask(SIG_UNBLOCK,&mask,NULL);
}

请!我需要帮助!

【问题讨论】:

    标签: c sockets unix signals sigprocmask


    【解决方案1】:

    您没有初始化struct sigactionsa_flags 字段,因此它可能包含垃圾值。可能设置了 SA_RESETHAND 位,根据手册页,它会给你这种行为:

           SA_RESETHAND
                  Restore the signal action to the default state once the signal handler has been called.  This flag  is
                  only  meaningful  when establishing a signal handler.  SA_ONESHOT is an obsolete, non-standard synonym
                  for this flag.
    

    如果您的信号处理程序已运行一次,这将导致它被清除并返回默认值,因此您可能只需将以下标志清零:

    void setSegnali(int segn,__sighandler_t handler){
      gestoreSegnale.sa_handler=handler;
      gestoreSegnale.sa_mask=mask;
      /* Make sure to clear flags */
      gestoreSegnale.sa_flags=0;
    
      sigaction(segn, &gestoreSegnale, NULL);
    }
    

    无论如何,下面这个小例子是可行的:

    #include <signal.h>
    #include <stdio.h>
    
    void handler(int sig) {
        printf("HUP %d\n", sig);
    }
    
    void main(){
        struct sigaction act;
    
        /* Block SIGHUP while the signal handler is running */
        sigemptyset(&act.sa_mask);
        sigaddset(&act.sa_mask,SIGHUP);
    
        /* Define handler for signal */
        act.sa_handler = handler;
    
        /* Clear flags */
        act.sa_flags = 0;
        act.sa_restorer = NULL;
    
        /* Install handler for SIGHUP */
        sigaction(SIGHUP, &act, NULL);
    
        /* Set mask to block SIGHUP */
        sigset_t mask;
        sigemptyset(&mask);
        sigaddset(&mask, SIGHUP);
    
        /* Block SIGHUP */
        printf("Blocking SIGHUP\n");
        sigprocmask(SIG_BLOCK,&mask,NULL);
        printf("Sleeping\n");
        sleep(60);
        /* Unblock SIGHUP */
        printf("Unblocking SIGHUP\n");
        sigprocmask(SIG_UNBLOCK,&mask,NULL);
        printf("Sleeping again\n");
        while(1)
            sleep(60);
    }
    

    如果运行,你会看到想要的结果:

    $ ./sigtest 
    Blocking SIGHUP
    Sleeping             <-- SIGHUP sent from another terminal here but blocked
    Unblocking SIGHUP
    HUP 1                <-- Signal sent earlier now delivered and handled
    Sleeping again
    HUP 1                <-- Further signals sent are all handled
    HUP 1
    HUP 1
    ^C
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-16
      • 1970-01-01
      • 2013-06-19
      相关资源
      最近更新 更多