2012-10-29 24 views
5

क्या कुछ सिग्नल को अवरुद्ध करने और उसी सेट में अन्य सिग्नल अनब्लॉक करने का कोई तरीका है? मुझे बस इसके चारों ओर मेरा सिर नहीं लग रहा है!पॉज़िक्स थ्रेड्स ब्लॉक सिग्नल और अनवरोधित

एक उदाहरण

sigset_t set; 
sigemptyset(&set); 

sigaddset(&set, SIGUSR1); 
// Block signal SIGUSR1 in this thread 
pthread_sigmask(SIG_BLOCK, &set, NULL); 
sigaddset(&set, SIGALRM); 
// Listen to signal SIGUSR2 
pthread_sigmask(SIG_UNBLOCK, &set, NULL); 


pthread_t printer_thread1, printer_thread2; 
pthread_create(&printer_thread1, NULL, print, (void *)&f1); 
pthread_create(&printer_thread2, NULL, print, (void *)&f2); 

bool tl = true; 
while(1) 
{ 
    if(tl) 
    { 
     // thread1 does something 
     kill(pid, SIGUSR1); 
     // main thread waits for SIGALRM 
     sigwait(&set, &sig); 
     tl = !tl; 
    } 
    else 
    { 
     // thread2 does something 
     kill(pid, SIGUSR2); 
     // main thread waits for SIGALRM 
     sigwait(&set, &sig); 
     tl = !tl; 
    } 
} 

मैं Mutexs, संकेतबाहु आदि केवल संकेतों का उपयोग करने की अनुमति नहीं कर रहा हूँ।

क्या कोई मदद कर सकता है? :)

+0

क्या आप पहले सिंकसआर 1 को अवरुद्ध नहीं कर रहे हैं और फिर अनब्लॉक नहीं कर रहे हैं? UNBLOCK के समय, सेट में SIGUSR1 और SIGALRM दोनों शामिल हैं। – amaurea

उत्तर

9

क्या कुछ सिग्नल को अवरुद्ध करने और में अन्य सिग्नल अनब्लॉक करने का कोई तरीका है?

  • अवरुद्ध संकेतों के सेट करने के लिए संकेत का एक सेट जोड़ने के लिए, निरंतर SIG_BLOCK
  • का उपयोग करके ब्लॉक के सेट करने के लिए संकेतों के एक समूह को हटाने:

pthread_sigmask साथ

, तो आप या तो चुन सकते हैं संकेत, निरंतर SIG_UNBLOCK

  • संकेतों के सेट का उपयोग को परिभाषित अवरुद्ध होने, लगातार SIG_SET
  • का उपयोग कर

    दूसरे शब्दों में, धागे के लिए अवरुद्ध संकेतों का एक वर्तमान सेट है, और आप इसे एक समय में एक ऑपरेशन के रूप में ऊपर निर्दिष्ट अनुसार संशोधित कर सकते हैं।

    महत्वपूर्ण बात यह है कि नव निर्मित धागे बनाने वाले थ्रेड के सिग्नल मास्क का उत्तराधिकारी होता है, ताकि आप इसे बनाने से पहले नए धागे का मुखौटा सेट कर सकें, या उस समारोह में जो नया थ्रेड चलाएगा, आपकी सुविधा पर ।

    अपने उदाहरण के बारे में, मुझे लगता है कि आप printer_thread1 ब्लॉक SIGUSR2 और SIGALRM के लिए कोशिश कर रहे हैं, और printer_thread2 ब्लॉक SIGUSR1 और SIGALRM है, और इतना है कि प्रत्येक थ्रेड एक संकेत है कि होगा भेज सकते हैं, मुख्य थ्रेड ब्लॉक SIGUSR1 और SIGUSR2 है एक थ्रेड द्वारा पकड़ा जा सकता है (print, f1 और f2 के कोड के बिना, यह सुनिश्चित करना असंभव है कि आपके उदाहरण में आपका इरादा क्या है)।

    आपको लगता है कि प्राप्त करने के लिए निम्न कोड से सक्षम होना चाहिए:

    sigset_t set; 
    pthread_t printer_thread1, printer_thread2; 
    
    
    // Block signal SIGUSR1 & SIGALRM in printer_thread1 
    sigemptyset(&set); 
    sigaddset(&set, SIGUSR1); 
    sigaddset(&set, SIGALRM); 
    pthread_sigmask(SIG_SET, &set, NULL); 
    pthread_create(&printer_thread1, NULL, print, (void *)&f1); 
    
    // Block signal SIGUSR2 & SIGALRM in printer_thread2 
    sigaddset(&set, SIGUSR2); 
    sigaddset(&set, SIGALRM); 
    pthread_sigmask(SIG_SET, &set, NULL); 
    pthread_create(&printer_thread2, NULL, print, (void *)&f2); 
    
    // Block signal SIGUSR1 & SIGUSR2 in the main thread 
    sigemptyset(&set); 
    sigaddset(&set, SIGUSR1); 
    sigaddset(&set, SIGUSR2); 
    // Listen to signal SIGALRM 
    pthread_sigmask(SIG_SET, &set, NULL); 
    
    
    bool tl = true; 
    while(1) 
    { 
        if(tl) 
        { 
         // thread1 does something 
         kill(pid, SIGUSR1); 
         // main thread waits for SIGALRM 
         sigwait(&set, &sig); 
         tl = !tl; 
        } 
        else 
        { 
         // thread2 does something 
         kill(pid, SIGUSR2); 
         // main thread waits for SIGALRM 
         sigwait(&set, &sig); 
         tl = !tl; 
        } 
    } 
    

    इन आदमी पृष्ठों को देखने के:

    अधिक जानकारी के लिए

    +0

    धन्यवाद, यह समझ में आता है, लेकिन यह वास्तव में प्रिंटर धागे के साथ काम नहीं करता है। लेकिन मैं समझता हूं कि मास्क अब कैसे काम करते हैं। – Max

    1

    मुझे लगता है कि तुम यहाँ क्या करना चाहते हैं

    // Block signal SIGUSR1 in this thread 
    sigemptyset(&set); 
    sigaddset(&set, SIGUSR1); 
    pthread_sigmask(SIG_BLOCK, &set, NULL); 
    
    // Listen to signal SIGALRM 
    sigemptyset(&set); 
    sigaddset(&set, SIGALRM); 
    pthread_sigmask(SIG_UNBLOCK, &set, NULL); 
    

    सेट केवल ब्लॉक या अनब्लॉक करने के लिए क्या यह बताने के लिए किया जाता है। एक बार आदेश पर जाने के बाद, आप इसे रीसेट करने और एक और सिग्नल मास्क बनाने के लिए स्वतंत्र हैं। यदि आप sigemptyset को छोड़ते हैं, तो सेट में अभी भी SIGUSR1 होगा, जिसे बाद में अनब्लॉक किया जाएगा। खैर, मुझे लगता है कि यह कैसे काम करता है, कम से कम - यह लंबे समय से रहा है क्योंकि मैंने संकेतों का उपयोग किया था।