ग्लोबल इंटरप्रेटर लॉक क्यों?


89

पायथन के ग्लोबल इंटरप्रेटर लॉक का कार्य वास्तव में क्या है? क्या अन्य भाषाएँ जो बायटेकोड के लिए संकलित हैं, एक समान तंत्र को नियोजित करती हैं?


6
आपको यह भी पूछना चाहिए "क्या यह भी मायने रखता है?"
S.Lott

2
मैं सहमत हूं, मैं इसे अब एक गैर-मुद्दा मानता हूं कि 2.6 में मल्टीप्रोसेसिंग मॉड्यूल को एक सूत्र की तरह कई प्रक्रियाओं का उपयोग करके प्रोग्राम करने की अनुमति देने के लिए जोड़ा गया था। docs.python.org/library/multiprocessing.html
monkut

जवाबों:


69

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

  • आप बारीक-बारीक लॉकिंग का उपयोग कर सकते हैं, जहां हर अलग संरचना का अपना लॉक होता है।

  • आप मोटे अनाज वाले लॉकिंग का उपयोग कर सकते हैं जहां एक लॉक सब कुछ (जीआईएल दृष्टिकोण) की रक्षा करता है।

प्रत्येक विधि के विभिन्न पेशेवरों और विपक्ष हैं। बारीक दाने वाली लॉकिंग अधिक समानता की अनुमति देती है - दो धागे समानांतर में निष्पादित कर सकते हैं जब वे किसी भी संसाधन को साझा नहीं करते हैं। हालाँकि बहुत बड़ा प्रशासनिक ओवरहेड है। कोड की प्रत्येक पंक्ति के लिए, आपको कई ताले प्राप्त करने और जारी करने की आवश्यकता हो सकती है।

मोटे दानेदार दृष्टिकोण इसके विपरीत है। दो धागे एक ही समय में नहीं चल सकते हैं, लेकिन एक अलग धागा तेजी से चलेगा क्योंकि यह इतना बहीखाता नहीं कर रहा है। अंततः यह एकल-थ्रेडेड गति और समानता के बीच एक ट्रेडऑफ के लिए नीचे आता है।

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

क्या अन्य भाषाएँ जो बायटेकोड के लिए संकलित हैं, एक समान तंत्र को नियोजित करती हैं?

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


1
क्या आप इसे समझा सकते हैं: 'दो धागे एक ही समय में नहीं चल सकते'? हाल ही में मैंने मल्टीथ्रेडिंग के साथ अजगर में एक साधारण वेबसर्वर लिखा। क्लाइंट से हर नए अनुरोध के लिए, सर्वर इसके लिए एक नया थ्रेड बंद कर देता है और उन थ्रेड को निष्पादित करना जारी रखता है। तो एक ही समय में कई थ्रेड चलेंगे? या मैंने गलत तरीके से समझा है?
avi

1
@avi AFAIK अजगर धागे एक साथ नहीं चल सकते हैं, लेकिन इसका मतलब यह नहीं है कि एक धागे को दूसरे को ब्लॉक करना चाहिए। GIL का मतलब केवल यह है कि केवल एक धागा एक बार में अजगर कोड की व्याख्या कर सकता है, इसका मतलब यह नहीं है कि धागा प्रबंधन और संसाधन आवंटन काम नहीं करता है।
बेन्प्रोडक्शन

2
^ इसलिए किसी भी समय बिंदु पर, केवल एक धागा ग्राहक को सामग्री प्रदान करेगा ... इसलिए वास्तव में प्रदर्शन को बेहतर बनाने के लिए मल्टीथ्रेडिंग का उपयोग करने का कोई मतलब नहीं है। सही?
avi

और, ज़ाहिर है, जावा को बाइट कोड के लिए संकलित किया गया है और बहुत बढ़िया दानेदार लॉकिंग की अनुमति देता है।
वॉरेन डेव

3
@avi, एक वेबसर्वर की तरह एक IO बाध्य प्रक्रिया अभी भी पायथन थ्रेड्स से प्राप्त कर सकती है। दो या अधिक धागे एक साथ IO कर सकते हैं। वे सिर्फ एक साथ (सीपीयू) व्याख्या नहीं कर सकते।
सास

33

निम्नलिखित आधिकारिक पायथन / सी एपीआई संदर्भ मैनुअल से है :

पायथन दुभाषिया पूरी तरह से सुरक्षित धागा नहीं है। बहु-थ्रेडेड पायथन कार्यक्रमों का समर्थन करने के लिए, एक वैश्विक ताला है जिसे वर्तमान धागे द्वारा सुरक्षित रूप से पायथन ऑब्जेक्ट्स तक पहुंचने से पहले आयोजित किया जाना चाहिए। लॉक के बिना, यहां तक ​​कि सबसे सरल संचालन भी एक बहु-थ्रेडेड प्रोग्राम में समस्याएं पैदा कर सकता है: उदाहरण के लिए, जब दो धागे एक साथ एक ही वस्तु के संदर्भ गणना को बढ़ाते हैं, तो संदर्भ गणना दो बार के बजाय केवल एक बार बढ़ाई जा सकती है।

इसलिए, नियम मौजूद है कि केवल वैश्विक इंटरप्रेटर लॉक का अधिग्रहण करने वाला धागा पायथन ऑब्जेक्ट्स पर काम कर सकता है या पायथन / सी एपीआई फ़ंक्शन को कॉल कर सकता है। बहु-पिरोया पायथन कार्यक्रमों का समर्थन करने के लिए, दुभाषिया नियमित रूप से रिलीज़ करता है और लॉक को फिर से प्राप्त करता है - डिफ़ॉल्ट रूप से, प्रत्येक 100 बायटेकोड निर्देश (इसे sys.setcheckinterval ()) के साथ बदला जा सकता है। लॉक को भी रिलीज़ किया जाता है और संभावित रूप से अवरुद्ध I / O संचालन के आसपास पुनः प्राप्त किया जाता है जैसे फ़ाइल पढ़ना या लिखना, ताकि अन्य थ्रेड्स चल सकें जबकि I / O अनुरोध करने वाले थ्रेड I / O ऑपरेशन के पूरा होने की प्रतीक्षा कर रहा है।

मुझे लगता है कि यह बहुत अच्छी तरह से इस मुद्दे को बोता है।


1
मैं इसे भी पढ़ता हूं, लेकिन मैं यह नहीं समझ सकता कि पायथन इस संबंध में अलग क्यों है, कहते हैं, जावा (यह है?)
फेडेरिको ए। रामपोनी

@EliBendersky पायथन थ्रेड्स पायथ के रूप में कार्यान्वित किए जाते हैं और ओएस ( dabeaz.com/python/UnderstandingGIL.pdf ) द्वारा संभाले जाते हैं, जबकि Java थ्रेड्स आवेदन स्तर के थ्रेड्स हैं, जिन्हें JVM द्वारा नियंत्रित किया जाता है
gokul_uf

19

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

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

यह प्रश्न भी देखें


4
"यह तंत्र बाइटकोड द्वारा संकलित होने वाले पायथन से संबंधित नहीं है": संक्षेप में, यह सीपीयॉन के कार्यान्वयन की एक कलाकृति है। अन्य कार्यान्वयन (जैसे कि ज्यथोन जिसका आपने उल्लेख किया है) उनके थ्रेड-सुरक्षित कार्यान्वयन के गुण द्वारा इस प्रतिबंध से मुक्त हो सकते हैं
एली बेन्द्स्की

11

पायल 5 की तरह, पायथन को जमीन से डिज़ाइन नहीं किया गया था ताकि धागा सुरक्षित रहे। इस तथ्य के बाद थ्रेड्स का मसौदा तैयार किया गया था, इसलिए पारस्परिक व्याख्या को बनाए रखने के लिए वैश्विक दुभाषिया लॉक का उपयोग किया जाता है, जहां केवल एक धागा दुभाषिया के आंतों में एक निश्चित समय पर कोड निष्पादित कर रहा है।

व्यक्तिगत पायथन थ्रेड्स को इंटरप्रेटर द्वारा सहकारी रूप से लॉक किया जाता है ताकि हर बार लॉक को साइकलिंग किया जा सके।

ताला को हथियाने की जरूरत तब पड़ती है जब आप C से अजगर से बात कर रहे होते हैं जब अन्य Python धागे इस प्रोटोकॉल में 'ऑप्ट' करने के लिए सक्रिय होते हैं और सुनिश्चित करते हैं कि आपकी पीठ के पीछे असुरक्षित कुछ भी नहीं होता है।

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


इस तथ्य का उल्लेख करने के लिए +1 कि मोटे अनाज वाले लॉकिंग का उपयोग सबसे अधिक सोचने की तुलना में किया जाता है, विशेष रूप से अक्सर भूल गए बीकेएल (मैं उपयोग करता हूं reiserfs- एकमात्र वास्तविक कारण जो मुझे इसके बारे में पता है)।
new123456

3
लिनक्स में BKL था, चूंकि संस्करण 2.6.39, BKL को पूरी तरह से हटा दिया गया है।
avi

5
बेशक। ध्यान रहे कि मैं इस सवाल का जवाब देने के बाद ~ 3 साल का था। =)
एडवर्ड KMETT

7

आपके दूसरे प्रश्न के बारे में, सभी स्क्रिप्टिंग भाषाएं इसका उपयोग नहीं करती हैं, लेकिन यह केवल उन्हें कम शक्तिशाली बनाता है। उदाहरण के लिए, रूबी में धागे हरे रंग के होते हैं, देशी नहीं।

पायथन में, धागे मूल हैं और जीआईएल केवल उन्हें अलग-अलग कोर पर चलने से रोकता है।

पर्ल में, धागे और भी बदतर हैं। वे बस पूरे दुभाषिया की नकल करते हैं, और अजगर के रूप में प्रयोग करने योग्य होने से बहुत दूर हैं।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.