【问题标题】:Is it valid to have multiple signal handlers for same signal?对同一个信号有多个信号处理程序是否有效?
【发布时间】:2013-06-14 07:06:00
【问题描述】:

我有两个共享库链接到我的测试应用程序。这两个库都有SIGINT 的信号处理程序。

对同一信号使用多个信号处理程序是否有效?当我生成SIGINT 信号时,处理程序将执行哪个顺序?

【问题讨论】:

    标签: c linux signals


    【解决方案1】:

    正如其他人所说,只能设置一个信号处理程序,即最后一个。然后,您必须自己管理调用两个函数。 sigaction 函数可以返回之前安装的信号处理程序,您可以自己调用它。

    类似这样的东西(未经测试的代码):

    /* other signal handlers */
    static void (*lib1_sighandler)(int) = NULL;
    static void (*lib2_sighandler)(int) = NULL;
    
    static void aggregate_handler(int signum)
    {
        /* your own cleanup */
        if (lib1_sighandler)
            lib1_sighandler(signum);
        if (lib2_sighandler)
            lib2_sighandler(signum);
    }
    
    ... (later in main)
    struct sigaction sa;
    struct sigaction old;
    
    lib1_init(...);
    /* retrieve lib1's sig handler */
    sigaction(SIGINT, NULL, &old);
    lib1_sighandler = old.sa_handler;
    
    lib2_init(...);
    /* retrieve lib2's sig handler */
    sigaction(SIGINT, NULL, &old);
    lib2_sighandler = old.sa_handler;
    
    /* set our own sig handler */
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = aggregate_handler;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGINT, &sa, NULL);
    

    【讨论】:

    • 我们是否错过了if (lib1_sighandler) 块中的return;
    • @rajraj,不,为什么?我们需要调用 both 处理程序。 if 仅确保指针不为 NULL。以防万一,因为您不想在信号处理程序中崩溃。
    【解决方案2】:

    每个信号只能安装一个信号处理程序。只有最新安装的处理程序将处于活动状态。

    【讨论】:

      【解决方案3】:

      正如您在 sigaction 的手册页中看到的那样,新的信号处理程序替换旧的信号处理程序并返回旧的信号处理程序。

      如果您有两个未使用的信号(例如 SIGUSR1SIGUSR2),请将这些信号分配给 SIGINT 的两个信号处理程序。然后您可以为SIGINT 编写自己的信号处理程序,然后您可以根据需要提出所需的未使用信号。

      【讨论】:

        【解决方案4】:

        沙巴兹一针见血。但是,如果您正在寻找所有库都可以使用的东西(前提是您可以访问源代码),您可以按照以下方式进行操作:

        linked_list* sigint_handlers = NULL;
        
        void sighand_init(sighand_config_t* config) {
            struct sigaction action;
            memset(&signalaction, 0, sizeof(signalaction));
            action.sa_handler = &sighand_main;
        
            // Order is important, in case we get a signal during start-up
            sigint_handlers = linked_list_new();
            sigaction(SIGINT, &action);
        }
        
        void sighand_main(int signum) {
            if (signum == SIGINT) {
                linked_list_node* node = linked_list_head(sigint_handlers);
                while ((node = node->next) != NULL) {
                    node->object(signum);
                }
                if (sighand_config.exitonint) {
                    app_exit(0);
                }
            }
        }
        
        void sighand_add_int_handler(void (*handler)(int)) {
            if (handler == NULL) return;
            linked_list_add(sigint_handlers, handler);
        }
        
        void sighand_destroy() {
            ...
            linked_list_destroy(signint_handlers);
            ...
        }
        

        或者,您可以自己使用它,在加载每个库后,获取处理程序,然后调用 add_handler。大致如下:

        loadlibrary(lib1.so);
        sigaction1 = signalget(SIGINT);
        
        loadlibrary(lib2.so);
        sigaction2 = signalget(SIGINT);
        
        sighand_init(...);
        sighand_add_int_handler(sigaction1.sa_handler);
        sighand_add_int_handler(sigaction2.sa_handler);
        

        只是一些想法, 安东尼

        【讨论】:

          【解决方案5】:

          我们可以使用单个信号处理程序来处理多个信号,但是 但同一信号不可能有多个信号处理程序。

          void sig_handler(int signo)
          {
          if (signo == SIGINT)
          printf("received SIGINT 1\n"); 
          }
          void sig(int signo)
          {
               if (signo == SIGINT)
                  printf("received SIGINT 2\n");
          }
             int main(void)
            {
                if(signal(SIGINT, sig_handler) == SIG_ERR)
                    printf("\ncan't catch SIGINT\n");
          
                if (signal(SIGINT, sig) == SIG_ERR)
                    printf("\ncan't catch SIGINT\n");
            // A long long wait so that we can easily issue a signal to this process
               while(1) 
                 sleep(1);
               return 0;
            }
          

          如果您尝试运行此代码,您会发现为该信号设置了最后分配的信号处理程序。 我认为同一信号不可能有多个信号处理程序。

          【讨论】:

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