내 테스트 응용 프로그램에 연결된 두 개의 공유 라이브러리가 있습니다. 두 라이브러리 모두 SIGINT
에 대한 신호 핸들러가 있습니다.동일한 신호에 대해 다중 신호 처리기를 사용하는 것이 유효합니까?
동일한 신호에 대해 여러 개의 신호 처리기를 사용할 수 있습니까? SIGINT
신호를 생성 할 때 처리기가 실행하는 순서는 무엇입니까?
내 테스트 응용 프로그램에 연결된 두 개의 공유 라이브러리가 있습니다. 두 라이브러리 모두 SIGINT
에 대한 신호 핸들러가 있습니다.동일한 신호에 대해 다중 신호 처리기를 사용하는 것이 유효합니까?
동일한 신호에 대해 여러 개의 신호 처리기를 사용할 수 있습니까? SIGINT
신호를 생성 할 때 처리기가 실행하는 순서는 무엇입니까?
다른 사람들에 의해 말했듯이, 하나의 신호 처리기 만 설정할 수 있습니다. 이것은 마지막 신호 처리기입니다. 그러면 두 함수를 직접 호출하여 관리해야합니다. 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);
우리는 단일 신호 처리기로 다중 신호를 처리 할 수 있지만 신호를 처리 할 수 있지만 동일한 신호에 대해 다중 신호 처리기를 사용할 수는 없습니다.
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;
}
이 코드를 실행하려고하면 마지막으로 할당 된 신호 처리기가 해당 신호에 설정되어있는 것을 알게됩니다. 동일한 신호에 대해 다중 신호 처리기를 사용할 수 없다고 생각합니다.
신호 당 하나의 신호 처리기 만 설치할 수 있습니다. 최신 설치된 핸들러 만 활성화됩니다.
설명서 페이지의 sigaction에서 볼 수 있듯이 새로운 신호 처리기가 이전 신호 처리기를 대체하고 이전 신호 처리기가 반환됩니다.
두 개의 사용되지 않은 신호 (예 : SIGUSR1
및 SIGUSR2
)가있는 경우 해당 신호에 SIGINT
의 두 신호 처리기를 할당하십시오. 그런 다음 SIGINT
에 대한 고유 한 신호 처리기를 작성할 수 있습니다. 그런 다음 원하는 미사용 신호를 올릴 수 있습니다.
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);
그냥 몇 가지 생각, 앤서니
우리는'반환을 그리워 하는가? –
@rajraj, 아니, 왜? ** ** 두 핸들러를 호출해야합니다. 'if'는 포인터가 NULL이 아니라는 것을 확인합니다. 시그널 핸들러 내에서 충돌하는 것을 원하지 않기 때문에. – Shahbaz