कि लेख का कहना है:
"एक समारोह या तो रैत्रांत, धागा सुरक्षित, दोनों, या न हो सकता है।"
यह भी कहते हैं:
"गैर रैत्रांत कार्यों धागा असुरक्षित हैं"।
मैं देख सकता हूं कि यह कैसे एक गड़बड़ी का कारण बन सकता है। उनका मतलब है कि पुन: प्रवेश करने की आवश्यकता के रूप में दस्तावेज किए गए मानक फ़ंक्शंस को थ्रेड-सुरक्षित होने की भी आवश्यकता नहीं है, जो कि पॉज़िक्स लाइब्रेरीज़ आईआईआरसी (और पीओएसईक्स के बारे में भी सच है, यह भी एएनएसआई/आईएसओ पुस्तकालयों के बारे में सच है, आईएसओ धागे की कोई अवधारणा नहीं है और इसलिए थ्रेड-सुरक्षा की कोई अवधारणा नहीं है)। दूसरे शब्दों में, "यदि कोई फ़ंक्शन कहता है कि यह गैर-पुनर्वित्तक है, तो यह कह रहा है कि यह थ्रेड-असुरक्षित भी है"। यह एक तार्किक आवश्यकता नहीं है, यह सिर्फ एक सम्मेलन है।
यहां कुछ छद्म कोड है जो थ्रेड-सुरक्षित है (अच्छी तरह से, लॉकिंग इनवर्जन के कारण कॉलबैक को डेडलॉक्स बनाने के लिए बहुत अवसर है, लेकिन मान लीजिए कि दस्तावेज़ों में उपयोगकर्ताओं से बचने के लिए पर्याप्त जानकारी है) लेकिन फिर से प्रवेश नहीं ।, कॉलबैक इस दिनचर्या फिर से कॉल
take_global_lock();
int i = get_global_counter();
do_callback(i);
set_global_counter(i+1);
release_global_lock();
हैं, तो एक और कॉलबैक में जिसके परिणामस्वरूप, तो कॉलबैक के दोनों स्तरों में एक ही पैरामीटर मिल जाएगा (जो ठीक हो सकता है: यह वैश्विक काउंटर बढ़ाने के लिए, और कॉलबैक प्रदर्शन करने के लिए माना जाता है एपीआई के आधार पर), लेकिन काउंटर केवल एक बार बढ़ाया जाएगा (जो लगभग निश्चित रूप से एपीआई नहीं है जिसे आप चाहते हैं, इसलिए इसे प्रतिबंधित करना होगा)।
यह मानते हुए कि लॉक रिकर्सिव है, ज़ाहिर है। यदि लॉक गैर-पुनरावर्ती है, तो निश्चित रूप से कोड गैर-पुनर्वित्तक है, क्योंकि लॉक लेना दूसरी बार काम नहीं करेगा।
यहाँ कुछ छद्म कोड है जो "दुर्बलता से फिर से प्रवेशी" लेकिन नहीं थ्रेड-सुरक्षित है:
int i = get_global_counter();
do_callback(i);
set_global_counter(get_global_counter()+1);
अब यह कॉलबैक से समारोह कॉल करने के लिए ठीक है, लेकिन यह समारोह समवर्ती कॉल करने के लिए सुरक्षित नहीं है विभिन्न धागे से। सिग्नल हैंडलर से इसे कॉल करना भी सुरक्षित नहीं है, क्योंकि संकेत सिग्नल हैंडलर से फिर से प्रवेश करना सही समय पर होने पर सिग्नल हो सकता है। तो कोड उचित परिभाषा द्वारा गैर-पुन: प्रवेशकर्ता है।
यहां कुछ कोड है जो तर्कसंगत रूप से पूरी तरह से पुनः प्रवेश करने वाला है (सिवाय इसके कि मुझे लगता है कि मानक पुनर्विक्रेता और 'सिग्नल द्वारा गैर-बाधा' के बीच अंतर करता है, और मुझे यकीन नहीं है कि यह कहां गिरता है), लेकिन अभी भी धागा नहीं है- सुरक्षित:
int i = get_global_counter();
do_callback(i);
disable_signals(); // and any other kind of interrupts on your system
set_global_counter(get_global_counter()+1);
restore_signal_state();
एक एकल पिरोया एप्लिकेशन पर, यह सोचते हैं कि इस ओएस सब कुछ अक्षम होने की जरूरत है कि अक्षम करने का समर्थन करता है ठीक है,। यह महत्वपूर्ण बिंदु पर होने से पुन: प्रवेश को रोकता है। संकेतों को अक्षम करने के आधार पर, सिग्नल हैंडलर से कॉल करना सुरक्षित हो सकता है, हालांकि इस विशेष उदाहरण में कॉलबैक को पास किए गए पैरामीटर का अलग-अलग कॉल के लिए समान पैरामीटर का मुद्दा अभी भी है। हालांकि, यह अभी भी गलत बहु थ्रेडेड जा सकता है।
प्रैक्टिस में, गैर थ्रेड-सुरक्षित अक्सर गैर-पुन: प्रवेशकर्ता का तात्पर्य है, क्योंकि अनौपचारिक रूप से कुछ भी जो शेड्यूलर द्वारा थ्रेड होने के कारण गलत हो सकता है, और फ़ंक्शन को किसी अन्य थ्रेड से फिर से बुलाया जा सकता है, गलत होने पर थ्रेड को सिग्नल द्वारा बाधित किया जाता है, और फ़ंक्शन को सिग्नल हैंडलर से फिर से बुलाया जाता है। लेकिन फिर संकेतों को रोकने के लिए "फिक्स" (उन्हें अक्षम करना) समरूपता को रोकने के लिए "ठीक" से अलग है (ताले, आमतौर पर)। यह सबसे अच्छा अंगूठे का नियम है।
ध्यान दें कि मैंने यहां ग्लोबल्स को निहित किया है, लेकिन अगर फ़ंक्शन पैरामीटर के रूप में काउंटर और लॉक के लिए एक पॉइंटर के रूप में लिया गया तो वही विचार लागू होंगे। यह सिर्फ इतना है कि विभिन्न मामलों को थ्रेड-असुरक्षित या गैर-पुन: प्रवेशकर्ता होगा जब एक ही पैरामीटर के साथ बुलाया जाता है, बजाय सभी को बुलाया जाता है।
आपका दूसरा उदाहरण मुझे फिर से प्रवेश नहीं करता है। यदि परिवर्तन एक असंगत स्थिति छोड़ने में बाधित हो सकता है, और उस बिंदु पर एक सिग्नल होता है, और उस सिग्नल के हैंडलर फ़ंक्शन को कॉल करता है, तो आम तौर पर यह उछाल जाता है। यह एक पुन: प्रवेश मुद्दा है, धागा-सुरक्षा समस्या नहीं। –
आप सही हैं - जैसा कि आप नीचे कहते हैं, आपको बाद के उदाहरण के लिए संकेतों को प्रभावी ढंग से पुन: प्रवेश करने के लिए भी अक्षम करना होगा। – ConcernedOfTunbridgeWells
@ConcernedOfTunbridgeWells, यदि एक func अंदर ढेर का उपयोग करता है, तो यह एक अच्छा मौका है कि यह func पुनः प्रवेश नहीं है। क्यूं कर? – Alcott