programing

동일한 신호에 대해 여러 개의 신호 처리기를 갖는 것이 유효합니까?

skycolor 2023. 9. 24. 12:43
반응형

동일한 신호에 대해 여러 개의 신호 처리기를 갖는 것이 유효합니까?

제 시험 애플리케이션에 연결된 공유 라이브러리가 두 개 있습니다.두 라이브러리 모두 에 대한 신호 처리기가 있습니다.SIGINT.

동일한 신호에 대해 여러 개의 신호 처리기를 갖는 것이 유효합니까?다음 순서를 생성할 때 핸들러가 실행될 순서SIGINT신호?

다른 사람들이 말한 것처럼, 신호 처리기는 마지막인 하나만 설정할 수 있습니다.그러면 두 가지 기능을 직접 호출해야 합니다.이 기능은 이전에 설치된 신호 처리기를 반환할 수 있으며, 이를 통해 직접 전화를 걸 수 있습니다.

이와 같은 것(검증되지 않은 코드)

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

신호 처리기는 신호당 하나만 설치할 수 있습니다.최신 설치 처리기만 활성화됩니다.

단일 신호 핸들러로 다중 신호를 처리할 수 있지만 동일한 신호에 대해 다중 신호 핸들러를 가지는 것은 불가능합니다.

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

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

서명을 위한 맨 페이지에서 볼 수 있듯이 새 신호 처리기가 이전 신호 처리기를 대체하고 이전 신호 처리기가 반환됩니다.

사용하지 않는 신호가 두 개일 경우(예:SIGUSR1그리고.SIGUSR2), 두 신호 처리기에 해당 신호를 할당합니다.SIGINT. 그러면 다음에 대한 신호 처리기를 직접 작성할 수 있습니다.SIGINT따라서 필요한 미사용 신호를 원하는 대로 올릴 수 있습니다.

샤바즈가 정곡을 찔렀습니다.그러나 모든 라이브러리에서 사용할 수 있는 소스 코드에 액세스할 수 있는 경우 다음과 같은 작업을 수행할 수 있습니다.

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

그냥 생각 좀 해봐, 앤서니

언급URL : https://stackoverflow.com/questions/17102919/is-it-valid-to-have-multiple-signal-handlers-for-same-signal

반응형