2013-06-14 6 views
7

मेरे पास मेरे परीक्षण आवेदन से जुड़े दो साझा पुस्तकालय हैं। दोनों पुस्तकालयों में SIGINT के लिए सिग्नल हैंडलर हैं।क्या यह सिग्नल के लिए एकाधिक सिग्नल हैंडलर रखने के लिए मान्य है?

क्या यह सिग्नल के लिए एकाधिक सिग्नल हैंडलर रखने के लिए मान्य है? जब मैं SIGINT सिग्नल उत्पन्न करता हूं तो कौन से ऑर्डर हैंडलर निष्पादित करेंगे?

उत्तर

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

@राजराज, नहीं, क्यों? हमें ** ** ** दोनों हैंडलर कॉल करने की आवश्यकता है। 'If' केवल यह सुनिश्चित करता है कि पॉइंटर्स न्यूल नहीं हैं। बस मामले में, क्योंकि आप सिग्नल हैंडलर के अंदर क्रैश नहीं करना चाहते हैं। – 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 के लिए मैन पेज में देख सकते हैं, नया सिग्नल हैंडलर पुराने को बदल देता है और पुराना एक लौटा दिया जाता है।

आप दो अप्रयुक्त संकेतों (जैसे कि SIGUSR1 और SIGUSR2) है, तो उन संकेतों SIGINT के लिए दो संकेत संचालकों आवंटित। फिर आप SIGINT के लिए अपना खुद का सिग्नल हैंडलर लिख सकते हैं और उससे, आप आवश्यक अनुसार अप्रयुक्त सिग्नल बढ़ा सकते हैं।

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 को कॉल करें। की तर्ज पर कुछ: `` में अगर (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); 

बस कुछ विचार, एंथोनी

संबंधित मुद्दे