21

我有两个共享库链接到我的测试应用程序。这两个库都有用于SIGINT.

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

4

5 回答 5

23

正如其他人所说,只能设置一个信号处理程序,即最后一个。然后,您必须自己管理调用两个函数。该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);
于 2013-06-14T08:11:32.767 回答
9

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

于 2013-06-14T07:24:58.300 回答
2

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

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

于 2013-06-14T07:33:26.787 回答
2

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

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);

只是一些想法,安东尼

于 2013-09-03T00:37:13.503 回答
1

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

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;
  }

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

于 2013-06-14T07:24:48.173 回答