2012-10-18 19 views
12

मेरे मल्टीथ्रेड किए गए जीयूआई एप्लिकेशन में मेरे पास निम्न सिग्नल हैंडलिंग कोड है। मैं इतना है कि यह सही है और सूत्रण सुरक्षित हो जाएगा इस कोड में सुधार करना चाहते हैं, लेकिन वहाँ कुछ चीजें संकेत हैंडलिंग में मैं पूरी तरह से समझ में नहीं आता हैं:मल्टीथ्रेडेड वातावरण में सिग्नल हैंडलर फ़ंक्शन

  • संकेत प्रक्रिया या धागे स्तर पर नियंत्रित किया जाता है (मैं धागा हो सकता है विशिष्ट सिग्नल हैंडलर)?
  • जिसमें थ्रेड संदर्भ सिग्नल_हैंडलर फ़ंक्शन निष्पादित है?
  • क्या कम समय में कई सिगरेट सिग्नल भेजना संभव है?
  • क्या सिग्नल_हैंडलर के समानांतर निष्पादन को रोकने के लिए एक म्यूटेक्स का उपयोग करना समझ में आता है?

void signal_handler(int sig) 
{ 
     switch (sig) 
     { 
     case SIGTERM: 
      ::wxLogMessage(wxT("SIGTERM signal received ...")); 
      break; 
     case SIGINT: 
      ::wxLogMessage(wxT("SIGINT signal received ...")); 
      break; 
     case SIGUSR1: 
      ::wxLogMessage(wxT("SIGUSR1 signal received ...")); 
      break; 
     default: 
      ::wxLogMessage(wxT("Unknown signal received ...")); 
     } 

     // send wxCloseEvent to main application window 
     ::wxGetApp().GetTopWindow()->Close(true); 
} 

मैं अपने init समारोह में संकेत संचालकों रजिस्टर:

// register signal handlers 
signal(SIGTERM, signal_handler); 
signal(SIGINT, signal_handler); 
signal(SIGUSR1, signal_handler); 

उत्तर

10

बहुत सावधान: signal(7) पेज कह रहा है के रूप में, केवल बहुत कम कार्य ("async-संकेत -साफ " वाले) सिग्नल हैंडलर के अंदर बुलाया जा सकता है (सीधे या परोक्ष रूप से)। म्यूटेक्स से जुड़े कार्यों को सिग्नल हैंडलर में शायद नहीं कहा जाना चाहिए। यह भी देखें pthreads(7)

आप अपने सिग्नल हैंडलर में volatile sigatomic_t चर सेट करने पर विचार कर सकते हैं और समय-समय पर उस ध्वज के मूल्य का परीक्षण कर सकते हैं। यदि आपके पास C++ 11 (या C11) परमाणु हैं, उदा। सी ++ 11 std::atomic या सी 11 <stdatomic.h>, आप उस volatile वैरिएबल को उस अर्थ में परमाणु बना सकते हैं। फिर परीक्षण करने के लिए परमाणु लोड सुविधाओं का उपयोग करें।

क्यूटी प्रलेखन पता चलता है following trick: स्टार्टअप पर स्वयं के लिए एक pipe(2) बनानी होगी, फिर संकेत हैंडलर write(2) एक एकल (या अधिक) बाइट [एस] के लिए (write syscall async-संकेत सुरक्षित होने के रूप में निर्दिष्ट किया जाता है) है एक ही प्रक्रिया में एक पाइप, और उस जीआईआई घटना लूप poll(2) उस पाइप के पढ़ने के अंत है।

एक लिनक्स विशिष्ट तरह से क्यूटी साथ संकेतों को संभालने के लिए signalfd(2)QSocketNotifier साथ शायद उपयोग करने के लिए हो सकता है (नाम के बावजूद, यह pollable फ़ाइल वर्णनकर्ता पर काम करता है, न केवल सॉकेट)। अन्य जीयूआई टूलकिट्स के साथ, आप शायद एक फ़ाइल डिस्क्रिप्टर (signalfd या pipe से) को भी मतदान के लिए जोड़ सकते हैं।

+2

नोट सिग्नल हैंडलर में std :: परमाणु का उपयोग लॉक-मुक्त कार्यान्वयन की गारंटी नहीं देता है। कृपया देखें: http://www.informit.com/articles/article.aspx?p=2204014 – Corvusoft

4

यह उत्तर POSIX धागे (pthreads) को संदर्भित करता है।

1 जिक्र करते हुए:

सिग्नल धागा स्तर पर नियंत्रित किया जा सकता है, हाँ। यदि किसी प्रक्रिया के एक से अधिक थ्रेड सिग्नल को संभालते हैं और सिग्नल प्रक्रिया में भेजा जाता है, लेकिन एक विशिष्ट थ्रेड के लिए यह निर्धारित नहीं किया जाता है कि थ्रेड का हैंडलर सिग्नल को कैसे संभालेगा। (विवरण के लिए man pthread_kill() देखें)

जिक्र करते हुए 2:

संकेत हैंडलर धागा जो यह सेट के संदर्भ में excuted किया जाएगा। इसमें मुख्य धागा शामिल है।

3 जिक्र करते हुए:

एक ही प्रकार के एक से अधिक संकेत एक ही प्रक्रिया वे संकेत कतार रवाना होने से पहले केवल एक संकेत में में संघनित हो सकता है के लिए भेजा जाता है। चाहे यह थ्रेड स्तर से अलग हो सकता है, मुझे यकीन नहीं है, मुझे स्वीकार करना है।

4 जिक्र करते हुए: कम से कम संचालकों 'कोड समवर्ती उन संसाधनों तक पहुँचने के कुछ हिस्सों के लिए हाँ,:

साझा संसाधन खेल में शामिल हैं। और इसके अलावा यह उस तर्क पर निर्भर करता है जिसे आप कार्यान्वित करने का प्रयास करते हैं। एक ऐसी प्रक्रिया में हिस्सेदारी के सारे सूत्र स्थापित संकेत हैंडलर कार्यों का एक ही सेट जो है -

17
  • सिग्नल संचालकों प्रति प्रक्रिया राज्य कर रहे हैं।
  • सिग्नल मास्क प्रति-थ्रेड स्थिति हैं। सिग्नल प्रति-थ्रेड आधार पर अवरुद्ध या अनब्लॉक किया जा सकता है।
  • सिग्नल प्रक्रिया हो सकती है- या थ्रेड-निर्देशित। यदि सिग्नल प्रक्रिया-निर्देशित होता है, तो एक मनमाना धागा जिसमें वर्तमान में सिग्नल प्रकार अवरुद्ध नहीं होता है उसे संभालने के लिए चुना जाता है।

बहु-थ्रेडेड अनुप्रयोग में सिग्नल को संभालने का एक आसान तरीका एक थ्रेड को समर्पित सिग्नल-हैंडलिंग थ्रेड के रूप में बनाना है। प्रत्येक धागे में ब्याज के सभी संकेत अवरुद्ध हैं; कोई संकेत हैंडलर स्थापित नहीं हैं; और सिग्नल-हैंडलिंग थ्रेड sigwaitinfo() को लूप में कॉल करता है, सिग्नल पर प्राप्त होने पर उन्हें प्राप्त होता है।

इसका मतलब यह है कि आप, क्योंकि संकेत संकेत संचालकों में संभाला नहीं कर रहे हैं के बारे में कार्यों आप कॉल करना चाहते async-संकेत सुरक्षित हैं या नहीं चिंता करने की जरूरत नहीं है - वे से तुल्यकालिक संभाला रहे हैं अपने समर्पित सिग्नल-हैंडलिंग थ्रेड, जो किसी भी फ़ंक्शन को पसंद कर सकता है (उदाहरण के लिए, यह सामान्य थ्रेड्रेड सिंक्रनाइज़ेशन फ़ंक्शंस का उपयोग किसी अन्य थ्रेड को उठाने के लिए कर सकता है)।

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