我有两个链接到我的测试应用程序的共享库。这两个库都有SIGINT
的信号处理程序。
对于相同的信号有多个信号处理程序是否有效?当我生成SIGINT
信号时,处理程序将执行哪个顺序?
答案 0 :(得分:18)
正如其他人所说,只能设置一个信号处理程序,这是最后一个。然后,您必须自己管理调用两个函数。 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);
答案 1 :(得分:7)
每个信号只能安装一个信号处理程序。只有最新安装的处理程序才会处于活动状态。
答案 2 :(得分:2)
我们可以用单信号处理器处理多个信号但是 但它不可能有相同信号的多个信号处理程序。
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;
}
如果您尝试运行此代码,您将发现为该信号设置了最后分配的信号处理程序。 我认为不可能有相同信号的多信号处理程序。
答案 3 :(得分:1)
正如您在sigaction的手册页中看到的那样,新的信号处理程序将替换旧的信号处理程序,并返回旧的信号处理程序。
如果您有两个未使用的信号(例如SIGUSR1
和SIGUSR2
),请将这些信号分配给SIGINT
的两个信号处理程序。然后您可以为SIGINT
编写自己的信号处理程序,然后您可以根据需要提高所需的未使用信号。
答案 4 :(得分:1)
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);
只是一些想法, 安东尼