2010-04-04 14 views
72

मैं पॉज़िक्स थ्रेड और पॉज़िक्स सिग्नल कैसे इंटरैक्ट करते हैं, इसकी जटिलताओं को समझने की कोशिश कर रहा हूं। विशेष रूप से, मुझे इसमें दिलचस्पी है:पॉज़िक्स धागे और सिग्नल

  • यह नियंत्रित करने का सबसे अच्छा तरीका क्या है कि सिग्नल किस धागे को वितरित किया जाता है (माना जाता है कि यह पहली जगह घातक नहीं है)?
  • सिग्नल आ गया है कि एक और थ्रेड (वास्तव में व्यस्त हो सकता है) बताने का सबसे अच्छा तरीका क्या है? (मुझे पहले से ही पता है कि सिग्नल हैंडलर से पर्थ्रेड कंडीशन वेरिएबल्स का उपयोग करना एक बुरा विचार है।)
  • मैं अन्य थ्रेडों पर सिग्नल कितनी जानकारी प्राप्त कर रहा हूं, इस जानकारी को सुरक्षित रूप से कैसे संभाला जा सकता हूं? क्या सिग्नल हैंडलर में ऐसा होने की ज़रूरत है? कारण है कि मैं यह चाहता हूँ, मैं कैसे TclX पैकेज धागे का समर्थन करने के कन्वर्ट करने के लिए शोध कर रहा हूँ, या के बारे में संदर्भ के लिए

, (मैं एक बहुत ही सूक्ष्म दृष्टिकोण की जरूरत है मैं दूसरे धागे को मारने के लिए चाहता हूँ सामान्य रूप में नहीं है।) इसे विभाजित करने के लिए और कम से कम कुछ उपयोगी भागों धागे का समर्थन करते हैं। सिग्नल उन हिस्सों में से एक हैं जो विशेष रुचि के हैं।

उत्तर

42
  • जो धागा एक संकेत के लिए दिया जाता नियंत्रित करने के लिए सबसे अच्छा तरीका क्या है?

के रूप में @ zoli2k संकेत दिया, स्पष्ट रूप से सभी संकेतों आप संभाला करना चाहते हैं (या धागे विशिष्ट संकेत जिम्मेदारियों के साथ प्रत्येक का एक सेट) प्रबंधित करने के लिए धागा नामांकित, एक अच्छा तकनीक है।

  • सबसे अच्छा तरीका है एक और धागा (है कि वास्तव में व्यस्त हो सकता है) कि संकेत आ गया है बताने के लिए क्या है? [...]
  • कैसे मैं सुरक्षित रूप से एक संकेत है कि जानकारी गुजर संभाल कर सकते हैं अन्य धागे के लिए हुआ है? क्या सिग्नल हैंडलर में ऐसा होने की ज़रूरत है?

मैंने ऐसा नहीं होगा "सबसे अच्छा," लेकिन यहाँ मेरी सिफारिश है:

ब्लॉक सभी main में वांछित संकेतों, ताकि सभी धागे कि संकेत मुखौटा के वारिस हैं। फिर, सिग्नल-संचालित इवेंट लूप के रूप में विशेष संकेत प्राप्त थ्रेड को फ़ैशन करें, के रूप में नए आने वाले संकेतों को प्रेषित करें, कुछ अन्य इंट्रा-थ्रेड संचार

ऐसा करने का सबसे आसान तरीका यह है कि sigwaitinfo or sigtimedwait का उपयोग करके थ्रेड में धागे को सिग्नल स्वीकार करना है। धागा तो संकेत धर्मान्तरित किसी भी तरह, शायद एक pthread_cond_t प्रसारण, और मैं के साथ अन्य धागे जागने/हे, जो एप्लिकेशन-विशिष्ट धागे की सुरक्षित कतार में एक कमांड enqueuing, जो कुछ भी।

वैकल्पिक रूप से, विशेष धागा संकेत एक संकेत हैंडलर के लिए दिया जा सकता है, केवल जब तैयार संकेतों को संभालने के लिए प्रसव के लिए unmasking अनुमति दे सकता है। (हैंडलर के माध्यम से सिग्नल डिलीवरी sigwait परिवार के माध्यम से सिग्नल स्वीकृति से अधिक त्रुटि-प्रवण होती है।) इस मामले में, रिसीवर का सिग्नल हैंडलर कुछ सरल और एसिंक-सिग्नल-सुरक्षित कार्रवाई करता है: sig_atomic_t फ़्लैग सेट करना, sigaddset(&signals_i_have_seen_recently, latest_sig), write पर कॉल करना() एक गैर अवरुद्ध self-pipe करने के लिए एक बाइट, आदि फिर, अपनी नकाबपोश मुख्य पाश में वापस, धागा, जैसा कि ऊपर अन्य थ्रेड के लिए संकेत प्राप्त होने संचार करता है।

(UPDATED ठीक ही बताते हैं @caf कि sigwait दृष्टिकोण बेहतर हैं।)

+0

यह एक बहुत अधिक उपयोगी उत्तर है, विशेष रूप से इसका उपयोग गैर-घातक सिग्नल हैंडलिंग को संभालने के लिए भी किया जा सकता है। धन्यवाद! –

+1

सिग्नल हैंडलिंग थ्रेड सिग्नल हैंडलर को इंस्टॉल नहीं करता है, इसके बजाय यह सबसे आसान है - इसके बजाय, यह 'sigwaitinfo() '(या' sigtimedwait() ') पर घूमता है, और फिर वर्णित अनुसार शेष एप्लिकेशन पर भेजता है अंतिम अनुच्छेद में। – caf

+0

@ कैफ, वास्तव में ऐसा है। अपडेट किया गया – pilcrow

13

पॉज़िक्स मानक के अनुसार सभी धागे सिस्टम पर एक ही पीआईडी ​​के साथ दिखाई दे सकते हैं और pthread_sigmask() का उपयोग करके आप प्रत्येक थ्रेड के लिए सिग्नल अवरुद्ध मास्क को परिभाषित कर सकते हैं।

चूंकि इसे प्रति पीआईडी ​​में केवल एक सिग्नल हैंडलर को परिभाषित करने की अनुमति है, इसलिए मैं एक थ्रेड में सभी संकेतों को संभालना पसंद करता हूं और pthread_cancel() भेजता हूं यदि कोई चलने वाले थ्रेड को रद्द करने की आवश्यकता है। pthread_kill() के खिलाफ यह पसंदीदा तरीका है क्योंकि यह थ्रेड के लिए क्लीनअप फ़ंक्शंस को परिभाषित करने की अनुमति देता है।

कुछ पुराने सिस्टम पर, उचित कर्नेल समर्थन की कमी के कारण, चलने वाले धागे में पैरेंट थ्रेड के पीआईडी ​​से अलग पीआईडी ​​हो सकती है। linuxThreads on Linux 2.4 के साथ सिग्नल हैंडलिंग के लिए अक्सर पूछे जाने वाले प्रश्न देखें।

+0

जो आपने कहा "कार्यान्वित" का अर्थ है क्या? साथ ही, सिग्नल के जवाब में हमेशा अन्य धागे को नकारना सही नहीं है (SIGHUP और SIGWINCH को अधिक सूक्ष्मता की आवश्यकता होती है) और फिर भी अन्य धागे को जानने के लिए हालत चर का उपयोग करना असुरक्षित है। गरीब जवाब –

+0

@ डोनल फैलो> पोस्ट संपादित। मुझे उम्मीद है कि यह अब और अधिक सहायक है। – zoli2k

+1

मेरा डाउन-वोट हटा दिया गया, लेकिन यह अभी भी पर्याप्त उत्तर नहीं है क्योंकि मैं सिग्नल के जवाब में केवल धागे को मार नहीं सकता। कुछ मामलों में मैं प्रतिक्रिया में स्थानीय रूप से क्यूइंग कार्यक्रमों के लिए जा रहा हूं, दूसरों में मुझे धागे को बहुत सावधानी से फाड़ना होगा (बीटीडब्लू, मुझे पहले से ही उन हिस्सों को करने के लिए मशीनरी मिल गई है; यह ओएस के कनेक्शन है सिग्नल जो गायब हैं)। –

3

कहाँ मैं अब तक पर हूँ:

  • सिग्नल विभिन्न प्रमुख वर्गों में आते हैं, जिनमें से कुछ आम तौर पर सिर्फ प्रक्रिया वैसे भी (SIGILL) को मार देना चाहिए और जिनमें से कुछ कभी नहीं कुछ भी करने (SIGIO की जरूरत है; आसान वैसे भी async आईओ ठीक करने के लिए)। उन दो वर्गों को कोई कार्रवाई की आवश्यकता नहीं है।
  • कुछ सिग्नल तुरंत निपटने की आवश्यकता नहीं है; SIGWINCH की पसंद को तब तक कतारबद्ध किया जा सकता है जब तक कि यह सुविधाजनक न हो (बस X11 से एक ईवेंट की तरह)।
  • मुश्किल लोग वे हैं जहां आप जो भी कर रहे हैं उसे बाधित करके उन्हें जवाब देना चाहते हैं लेकिन धागे को पोंछने की सीमा तक जाकर। विशेष रूप से, इंटरैक्टिव मोड में SIGINT चीजों को उत्तरदायी छोड़ना चाहिए।

मैं अभी भी के माध्यम से सॉर्ट करने के लिए मिल गया है signalsigaction बनाम, pselect, sigwait, sigaltstack, और अन्य बिट्स और POSIX (और गैर POSIX) एपीआई के टुकड़े की एक पूरी गुच्छा।

4

IMHO, यूनिक्स वी संकेतों और POSIX धागे नहीं घुलते हैं। यूनिक्स वी 1970 POSIX 1980 है;)

रद्द अंक हैं और अगर आप एक आवेदन में संकेतों और pthreads अनुमति देते हैं, तो आप अंत में प्रत्येक कॉल, जो आश्चर्यजनक रूप से EINTR लौट सकते हैं चारों ओर लूप्स लेखन खत्म हो जाएगा।

तो मैंने (कुछ) मामलों में क्या किया जहां मुझे लिनक्स या क्यूएनएक्स पर बहुप्रचारित कार्यक्रम करना था, सभी (लेकिन एक) धागे के लिए सभी संकेतों को मुखौटा करना था।

जब यूनिक्स वी सिग्नल आता है, तो प्रक्रिया स्टैक को स्विच करती है (जो यूनिक्स वी में उतनी ही समरूपता थी जितनी आप एक प्रक्रिया में प्राप्त कर सकते थे)।

अन्य पदों यहाँ संकेत के रूप में, यह संभव अब प्रणाली है, जो POSIX धागे कि ढेर स्विचिंग का शिकार हो जाएगा बताने के लिए हो सकता है,।

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

तो, अन्य धागे को रद्द करने या उन्हें (या अन्य अजीब सामान) को मारने के बजाय, आपको सिग्नल संदर्भ से सिग्नल को अपने सिग्नल हैंडलर थ्रेड पर मिशेल करने का प्रयास करना चाहिए, फिर अपने अभिनेता पैटर्न संचार तंत्र का उपयोग अर्थपूर्ण रूप से उपयोगी संदेश भेजने के लिए करें उन कलाकारों को, जिन्हें सिग्नल से संबंधित जानकारी की आवश्यकता है।

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