2013-06-14 2 views

답변

14

다른 사람들에 의해 말했듯이, 하나의 신호 처리기 만 설정할 수 있습니다. 이것은 마지막 신호 처리기입니다. 그러면 두 함수를 직접 호출하여 관리해야합니다. 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); 
+0

우리는'반환을 그리워 하는가? –

+0

@rajraj, 아니, 왜? ** ** 두 핸들러를 호출해야합니다. 'if'는 포인터가 NULL이 아니라는 것을 확인합니다. 시그널 핸들러 내에서 충돌하는 것을 원하지 않기 때문에. – Shahbaz

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

이 코드를 실행하려고하면 마지막으로 할당 된 신호 처리기가 해당 신호에 설정되어있는 것을 알게됩니다. 동일한 신호에 대해 다중 신호 처리기를 사용할 수 없다고 생각합니다.

6

신호 당 하나의 신호 처리기 만 설치할 수 있습니다. 최신 설치된 핸들러 만 활성화됩니다.

1

설명서 페이지의 sigaction에서 볼 수 있듯이 새로운 신호 처리기가 이전 신호 처리기를 대체하고 이전 신호 처리기가 반환됩니다.

두 개의 사용되지 않은 신호 (예 : SIGUSR1SIGUSR2)가있는 경우 해당 신호에 SIGINT의 두 신호 처리기를 할당하십시오. 그런 다음 SIGINT에 대한 고유 한 신호 처리기를 작성할 수 있습니다. 그런 다음 원하는 미사용 신호를 올릴 수 있습니다.

1

Shabaz은 머리에 못을했다. 당신이 모든 라이브러리를 사용할 수있는 뭔가를 찾고있는 경우, 다음과 같은 라인을 따라 뭔가 할 수있는 (소스 코드에 액세스 할 수 제공) : 사용자가 직접이 사용할 수,

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를 호출하십시오. 의 라인을 따라 뭔가 :;`에서`경우 (lib1_sighandler)`블록

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

그냥 몇 가지 생각, 앤서니

관련 문제