थ्रेड सेफ्टी

थ्रेड सुरक्षा कंप्यूटर प्रोग्रामिंग सिद्धांत है जो मल्टी-थ्रेडेड कोड पर लागू होता है। थ्रेड-सेफ कोड केवल साझा डेटा संरचनाओं में चालाकी करता है जो यह सुनिश्चित करता है कि सभी थ्रेड ठीक से व्यवहार करें और बिना किसी अनपेक्षित इंटरैक्शन के अपने डिज़ाइन विनिर्देशों को पूरा करें। थ्रेड-सुरक्षित डेटा संरचनाएँ बनाने के लिए विभिन्न कार्यनीतियाँ हैं।

प्रोग्राम एक साझा पता स्थान में एक साथ कई थ्रेड्स में कोड निष्पादित कर सकता है, जहां उन थ्रेड्स में से प्रत्येक के पास हर दूसरे थ्रेड के लगभग सभी कंप्यूटर भंडारण तक पहुंच होती है। थ्रेड सुरक्षा गुण है जो नियंत्रण के वास्तविक प्रवाह और कार्यक्रम के पाठ के बीच समकालीन के माध्यम से कुछ पत्राचार को पुन: स्थापित करके कोड को बहुप्रचारित वातावरण में चलाने की अनुमति देती है।

थ्रेड सुरक्षा के स्तर
सॉफ्टवेयर पुस्तकालय कुछ थ्रेड-सुरक्षा गारंटी प्रदान कर सकती है। उदाहरण के लिए, समवर्ती पठन को थ्रेड-सुरक्षित होने की गारंटी दी जा सकती है, लेकिन समवर्ती लेखन नहीं हो सकता है। ऐसी पुस्तकालय का उपयोग करने वाला कोई प्रोग्राम थ्रेड-सुरक्षित है या नहीं, यह इस बात पर निर्भर करता है कि क्या वह पुस्तकालय का उपयोग उन गारंटियों के अनुरूप तरीके से करता है।

अलग-अलग विक्रेता थ्रेड-सुरक्षा के लिए थोड़ी अलग शब्दावली का उपयोग करते हैं
 * थ्रेड सुरक्षित: जब एक साथ कई थ्रेड्स द्वारा एक्सेस किए जाने पर निष्पादन को दौड़ की स्थिति से मुक्त होने की गारंटी दी जाती है।
 * सशर्त रूप से सुरक्षित: विभिन्न थ्रेड्स एक साथ विभिन्न वस्तुओं तक पहुंच सकते हैं, और साझा किए गए डेटा तक पहुंच दौड़ की स्थिति से सुरक्षित है।
 * नॉट थ्रेड्स सेफ: डेटा संरचनाएं को विभिन्न थ्रेड्स द्वारा एक साथ एक्सेस नहीं किया जाना चाहिए।

थ्रेड सुरक्षा गारंटी में प्रायः गतिरोध के विभिन्न रूपों के जोखिम को रोकने या सीमित करने के लिए डिज़ाइन चरण शामिल होते हैं, साथ ही समवर्ती प्रदर्शन को अधिकतम करने के लिए अनुकूलन भी शामिल होते हैं। हालांकि, डेडलॉक-मुक्त गारंटी हमेशा नहीं दी जा सकती है, क्योंकि डेडलॉक कॉलबैक और पुस्तकालय से स्वतंत्र वास्तु परत के उल्लंघन के कारण हो सकते हैं।

कार्यान्वयन दृष्टिकोण
नीचे हम दौड़ की स्थिति से बचने के लिए दृष्टिकोणों के दो वर्गों पर चर्चा करते हैं # थ्रेड-सुरक्षा प्राप्त करने के लिए कंप्यूटिंग।

दृष्टिकोणों की पहली श्रेणी साझा स्थिति से बचने पर केंद्रित है और इसमें शामिल हैं:
 * रेंट्रेंट (सबरूटीन) | री-एंट्रेंसी: इस तरह से कोड लिखना कि इसे आंशिक रूप से एक थ्रेड द्वारा निष्पादित किया जा सकता है, उसी थ्रेड द्वारा निष्पादित किया जा सकता है, या एक साथ दूसरे थ्रेड द्वारा निष्पादित किया जा सकता है और फिर भी मूल निष्पादन को सही ढंग से पूरा कर सकता है। इसके लिए स्थिर चर या वैश्विक चर चर या अन्य गैर-स्थानीय राज्य के बजाय प्रत्येक निष्पादन के लिए स्थानीय चर में राज्य (कंप्यूटर विज्ञान) की जानकारी की बचत की आवश्यकता होती है। सभी गैर-स्थानीय राज्यों को परमाणु संचालन के माध्यम से एक्सेस किया जाना चाहिए और डेटा-संरचना भी पुनः प्रवेशी होनी चाहिए।
 * थ्रेड-लोकल स्टोरेज: वेरिएबल्स को स्थानीयकृत किया जाता है ताकि प्रत्येक थ्रेड की अपनी निजी प्रति हो। ये चर अपने मूल्यों को सबरूटीन और अन्य कोड सीमाओं में बनाए रखते हैं और थ्रेड-सुरक्षित होते हैं क्योंकि वे प्रत्येक थ्रेड के लिए स्थानीय होते हैं, भले ही उन्हें एक्सेस करने वाले कोड को एक साथ दूसरे थ्रेड द्वारा निष्पादित किया जा सकता है।
 * अपरिवर्तनीय वस्तुएँ: निर्माण के बाद किसी वस्तु की स्थिति को नहीं बदला जा सकता है। इसका अर्थ यह है कि केवल पढ़ने के लिए डेटा साझा किया जाता है और अंतर्निहित थ्रेड सुरक्षा प्राप्त की जाती है। म्यूटेबल (गैर-स्थिरांक) संचालन तब इस तरह से कार्यान्वित किया जा सकता है कि वे मौजूदा वस्तुओं को संशोधित करने के बजाय नई वस्तुएं बनाते हैं। यह दृष्टिकोण कार्यात्मक प्रोग्रामिंग की विशेषता है और इसका उपयोग जावा, सी # और पायथन में स्ट्रिंग कार्यान्वयन द्वारा भी किया जाता है। (अपरिवर्तनीय वस्तु देखें।)

दूसरी श्रेणी के दृष्टिकोण तुल्यकालन से संबंधित हैं, और उन स्थितियों में उपयोग किए जाते हैं जहां साझा स्थिति से बचा नहीं जा सकता है:
 * पारस्परिक बहिष्करण: साझा किए गए डेटा तक पहुंच तंत्र का उपयोग करके क्रमबद्ध है जो यह सुनिश्चित करता है कि किसी भी समय साझा किए गए डेटा को केवल एक थ्रेड पढ़ता या लिखता है। पारस्परिक बहिष्करण को शामिल करने पर अच्छी तरह से विचार करने की आवश्यकता है, क्योंकि अनुचित उपयोग से गतिरोध, livelock ्स और संसाधन भुखमरी जैसे दुष्प्रभाव हो सकते हैं।
 * रैखिकता: साझा डेटा को परमाणु संचालन का उपयोग करके एक्सेस किया जाता है जिसे अन्य थ्रेड्स द्वारा बाधित नहीं किया जा सकता है। इसके लिए आमतौर पर विशेष मशीन भाषा निर्देशों का उपयोग करने की आवश्यकता होती है, जो क्रम पुस्तकालय  में उपलब्ध हो सकते हैं। चूंकि ऑपरेशन परमाणु हैं, साझा डेटा हमेशा वैध स्थिति में रहता है, इससे कोई फर्क नहीं पड़ता कि अन्य धागे इसे कैसे एक्सेस करते हैं। परमाणु संचालन कई थ्रेड लॉकिंग तंत्रों का आधार बनता है, और पारस्परिक बहिष्करण आदिम को लागू करने के लिए उपयोग किया जाता है।

उदाहरण
जावा (प्रोग्रामिंग भाषा) कोड के निम्नलिखित भाग में, जावा कीवर्ड की जावा कीवर्ड सूची # सिंक्रोनाइज़ विधि को थ्रेड-सुरक्षित बनाती है:

C (प्रोग्रामिंग लैंग्वेज) में, प्रत्येक थ्रेड का अपना स्टैक होता है। हालाँकि, एक स्थिर चर को स्टैक पर नहीं रखा जाता है; सभी थ्रेड्स इसके लिए एक साथ पहुंच साझा करते हैं। यदि एक ही फ़ंक्शन को चलाने के दौरान एकाधिक धागे ओवरलैप होते हैं, तो यह संभव है कि एक स्थिर चर को एक थ्रेड द्वारा बदला जा सकता है जबकि दूसरा इसे जांचने के बीच में है। यह कठिन-से-निदान तर्क त्रुटि, जो अधिकांश समय संकलित और ठीक से चल सकती है, को दौड़ की स्थिति # सॉफ़्टवेयर कहा जाता है। इससे बचने का एक आम तरीका यह है कि दूसरे साझा चर को लॉक (कंप्यूटर विज्ञान) के रूप में उपयोग किया जाए लॉक या म्यूटेक्स (पारस्परिक बहिष्करण से)।

सी कोड के निम्नलिखित भाग में, फ़ंक्शन थ्रेड-सुरक्षित है, लेकिन पुनर्वित्तक नहीं है:

<स्पैन क्लास = एंकर आईडी = म्यूटेक्स उदाहरण> ऊपरोक्त में,  बिना किसी समस्या के अलग-अलग थ्रेड्स द्वारा कॉल किया जा सकता है क्योंकि म्यूटेक्स का उपयोग साझा किए गए सभी एक्सेस को सिंक्रोनाइज़ करने के लिए किया जाता है   चर। लेकिन अगर फ़ंक्शन का उपयोग रीएन्ट्रेंट इंटरप्ट हैंडलर में किया जाता है और म्यूटेक्स लॉक होने पर दूसरा इंटरप्ट उत्पन्न होता है, तो दूसरा रूटीन हमेशा के लिए लटका रहेगा। चूंकि इंटरप्ट सर्विसिंग अन्य इंटरप्ट्स को निष्क्रिय कर सकती है, इसलिए पूरा सिस्टम प्रभावित हो सकता है।

सी ++ 11 में लॉक-फ्री रैखिकता का उपयोग करके एक ही फ़ंक्शन को थ्रेड-सुरक्षित और पुनर्वित्तक दोनों के रूप में कार्यान्वित किया जा सकता है:

यह भी देखें

 * समरूपता नियंत्रण
 * अपवाद सुरक्षा
 * प्राथमिकता उलटा
 * सूत की अलमारी