CPython में वैश्विक दुभाषिया ताला (GIL) क्या है?


244

एक वैश्विक दुभाषिया ताला क्या है और यह एक मुद्दा क्यों है?

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


3
देखो डेविड बेज़ले आपको वह सब कुछ बताता है जो आप कभी जीआईएल के बारे में जानना चाहते थे।
ह्यूगब्रोर्न

1
यहाँ GIL और पायथन में थ्रेडिंग के बारे में एक लंबा लेख लिखा है, जो मैंने कुछ समय पहले लिखा था। यह इस पर विस्तार से उचित मात्रा में जाता है: jessenoller.com/2009/02/01/…
jnoller

यहाँ GIL के प्रभावों को प्रदर्शित करने वाले कुछ कोड हैं: github.com/cankav/python_gil_demon
Performance

3
मुझे लगता है कि यह जीआईएल की सबसे अच्छी व्याख्या है। कृपया पढ़ें। dabeaz.com/python/UnderstandingGIL.pdf
suhao399

realpython.com/python-gil मुझे यह उपयोगी लगा
qwr

जवाबों:


220

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

ध्यान दें कि पायथन की जीआईएल केवल सीपीथॉन के लिए एक मुद्दा है, संदर्भ कार्यान्वयन। Jython और IronPython में GIL नहीं है। पायथन डेवलपर के रूप में, आप आम तौर पर जीआईएल में नहीं आते हैं जब तक कि आप सी एक्सटेंशन नहीं लिख रहे हैं। C एक्सटेंशन लेखकों को GIL जारी करने की आवश्यकता होती है जब उनके एक्सटेंशन I / O को अवरुद्ध करते हैं, ताकि पायथन प्रक्रिया में अन्य थ्रेड्स को चलाने का मौका मिले।


46
अच्छा उत्तर - मूल रूप से इसका मतलब है कि पायथन में धागे केवल I / O को अवरुद्ध करने के लिए अच्छे हैं; आपका ऐप प्रोसेसर उपयोग के 1 सीपीयू कोर से ऊपर कभी नहीं जाएगा
एना बेट्स

8
"पायथन डेवलपर के रूप में, आप आम तौर पर जीआईएल में नहीं आते हैं जब तक कि आप एक सी एक्सटेंशन नहीं लिख रहे हैं" - आपको नहीं पता होगा कि घोंघे की गति से चलने वाले आपके बहु-थ्रेडेड कोड का कारण जीआईएल है, लेकिन आप ' निश्चित रूप से इसके प्रभाव महसूस करेंगे। यह अभी भी मुझे हैरान करता है कि पायथन के साथ 32-कोर सर्वर का लाभ उठाने का मतलब है कि मुझे सभी संबद्ध ओवरहेड के साथ 32 प्रक्रियाओं की आवश्यकता है।
बेसिक

6
@PaulBetts: यह सच नहीं है। यह संभावना है कि प्रदर्शन महत्वपूर्ण कोड पहले से ही सी एक्सटेंशन जो और गिल जैसे, जारी कर सकते हैं का उपयोग करता है regex, lxml, numpyमॉड्यूल। b2a_bin(data)
साइथॉन

5
@ पाओल बेट्स: आप मल्टीप्रोसेसिंग मॉड्यूल का उपयोग करके प्रोसेसर उपयोग के 1 सीपीयू कोड से ऊपर प्राप्त कर सकते हैं । एकाधिक थ्रेड्स बनाने की तुलना में कई प्रक्रियाएं बनाना "भारी वजन" है, लेकिन अगर आपको वास्तव में अजगर में समानांतर में काम करने की आवश्यकता है, तो यह एक विकल्प है।
एजेएनफेल्ड

1
@david_adler हां, अभी भी मामला है, और अभी तक कुछ समय तक बने रहने की संभावना है। यह वास्तव में कई अलग-अलग वर्कलोड के लिए पायथन को वास्तव में उपयोगी होने से नहीं रोकता है।
विनय साजिप

59

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

इसे एक वास्तविक विश्व सादृश्य में रखने के लिए: केवल एक कॉफी मग के साथ एक कंपनी में काम करने वाले 100 डेवलपर्स की कल्पना करें। अधिकांश डेवलपर्स कोडिंग के बजाय कॉफी के लिए इंतजार करने में अपना समय बिताते हैं।

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


सिवाय कॉफी मग के इंतजार के काफी हद तक I / O बाध्य प्रक्रिया लगती है, क्योंकि वे निश्चित रूप से मग के इंतजार के दौरान अन्य काम कर सकते हैं। GIL का I / O भारी धागों पर बहुत कम प्रभाव है जो अपना अधिकतर समय वैसे भी प्रतीक्षा करते हैं।
क्रंचर


36

आइए सबसे पहले समझते हैं कि अजगर जीआईएल क्या प्रदान करता है:

किसी भी ऑपरेशन / निर्देश को दुभाषिया में निष्पादित किया जाता है। जीआईएल सुनिश्चित करता है कि दुभाषिया किसी विशेष समय पर एक ही धागे से आयोजित किया जाता है । और कई थ्रेड्स के साथ आपका अजगर प्रोग्राम एक एकल दुभाषिया में काम करता है। किसी भी विशेष समय पर, यह दुभाषिया एक ही धागे द्वारा आयोजित किया जाता है। इसका मतलब यह है कि केवल जो धागा दुभाषिया धारण कर रहा है वह किसी भी समय चल रहा है

अब यह एक मुद्दा क्यों है:

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

हालाँकि, संभावित रूप से अवरुद्ध या लंबे समय तक चलने वाले ऑपरेशन, जैसे कि I / O, इमेज प्रोसेसिंग और NumPy नंबर क्रंचिंग, GIL के बाहर होते हैं। यहां से ले गए । इसलिए इस तरह के ऑपरेशन के लिए, जीआईएल की उपस्थिति के बावजूद एक थ्रेडेड ऑपरेशन सिंगल थ्रेडेड ऑपरेशन की तुलना में अधिक तेज़ होगा। इसलिए, GIL हमेशा एक अड़चन नहीं है।

संपादित करें: GIL CPython का कार्यान्वयन विवरण है। IronPython और Jython में GIL नहीं है, इसलिए उनमें वास्तव में एक बहुस्तरीय कार्यक्रम संभव होना चाहिए, मैंने सोचा कि मैंने कभी PyPy और Jython का उपयोग नहीं किया है और यह सुनिश्चित नहीं किया है।


4
नोट : PyPy में GIL हैसंदर्भ : http://doc.pypy.org/en/latest/faq.html#does-pypy-have-a-gil-why । जबकि आयरनपीथॉन और जेथॉन के पास GIL नहीं है।
तस्दीक रहमान

दरअसल, PyPy में एक GIL है, लेकिन IronPython नहीं है।
इमैनुअल

@Emmanuel ने PyPy को हटाने और IronPython को शामिल करने का उत्तर दिया।
अक्षर राज

17

पायथन शब्द के ट्रुस्ट अर्थ में मल्टी-थ्रेडिंग की अनुमति नहीं देता है। इसमें मल्टी-थ्रेडिंग पैकेज है, लेकिन यदि आप अपने कोड को गति देने के लिए मल्टी-थ्रेड करना चाहते हैं, तो आमतौर पर इसका उपयोग करना अच्छा नहीं है। पायथन में एक निर्माण है जिसे ग्लोबल इंटरप्रेटर लॉक (GIL) कहा जाता है।

https://www.youtube.com/watch?v=ph374fJqFPE

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

पायथन के थ्रेडिंग पैकेज का उपयोग करने के कारण हैं। यदि आप कुछ चीजों को एक साथ चलाना चाहते हैं, और दक्षता चिंता का विषय नहीं है, तो यह पूरी तरह से ठीक है और सुविधाजनक है। या यदि आप ऐसा कोड चला रहे हैं, जिसके लिए कुछ (जैसे कुछ IO) की प्रतीक्षा करने की जरूरत है तो यह बहुत मायने रख सकता है। लेकिन थ्रेडिंग लाइब्रेरी अभ्यस्त आपको अतिरिक्त सीपीयू कोर का उपयोग करने देगा।

मल्टी-थ्रेडिंग को ऑपरेटिंग सिस्टम (मल्टी-प्रोसेसिंग करके) के लिए आउटसोर्स किया जा सकता है, कुछ बाहरी एप्लिकेशन जो आपके पायथन कोड (जैसे, स्पार्क या हडोप) को कॉल करते हैं, या कुछ कोड जो आपके पायथन कोड को कॉल करते हैं (जैसे: आपके पास आपका पायथन हो सकता है) कोड एक सी फ़ंक्शन को बुलाता है जो महंगी बहु-थ्रेडेड सामान करता है)।


15

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

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

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

ध्यान दें कि यदि आपने C में उदाहरण के लिए C लिखा है, तो यह GIL जारी करना संभव है।

एक जीआईएल का उपयोग पायथन के लिए अंतर्निहित नहीं है, लेकिन इसके कुछ दुभाषिया में सबसे आम सीपीथॉन भी शामिल है। (#eded, टिप्पणी देखें)

पायथन 3000 में जीआईएल मुद्दा अभी भी मान्य है।


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

3.2 में नई GIL के बारे में क्या?
new123456

बस यह जोड़ने के लिए कि आपको कोई समस्या नहीं है / म्यूटेक्स / सेमाफोर की आवश्यकता है यदि केवल एक धागा मेमोरी को अपडेट करेगा। @ new123456 यह एकल-थ्रेडेड प्रदर्शन (जो अपने आप में प्रभावशाली है) को चोट पहुंचाए बिना विवाद और शेड्यूल थ्रेड को बेहतर बनाता है, लेकिन यह अभी भी एक वैश्विक लॉक है।
बेसिक

14

पायथन 3.7 प्रलेखन

मैं पायथन threadingप्रलेखन से निम्नलिखित उद्धरण को भी उजागर करना चाहूंगा :

CPython कार्यान्वयन विवरण: CPython में, ग्लोबल इंटरप्रेटर लॉक के कारण, केवल एक धागा पायथन कोड को एक ही बार में निष्पादित कर सकता है (भले ही कुछ प्रदर्शन उन्मुख पुस्तकालय इस सीमा को पार कर सकते हैं)। यदि आप चाहते हैं कि आपका एप्लिकेशन मल्टी-कोर मशीनों के कम्प्यूटेशनल संसाधनों का बेहतर उपयोग करे, तो आपको सलाह दी जाती है कि आप इसका उपयोग करें multiprocessingया concurrent.futures.ProcessPoolExecutor। हालाँकि, थ्रेडिंग अभी भी एक उपयुक्त मॉडल है यदि आप एक साथ कई I / O- बाउंड कार्य चलाना चाहते हैं।

यह ग्लोसरी प्रविष्टि के लिएglobal interpreter lock लिंक है जिसके बारे में बताते हैं कि GIL का अर्थ है कि Python में थ्रेडेड समानताएँ CPU बाध्य कार्यों के लिए अनुपयुक्त है :

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

हालांकि, कुछ विस्तार मॉड्यूल, या तो मानक या तीसरे पक्ष के होते हैं, ताकि कंपिल या हैशिंग जैसे कम्प्यूटेशनल-गहन कार्यों को करते समय GIL को जारी किया जा सके। साथ ही, GIL हमेशा I / O करते समय जारी किया जाता है।

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

इस उद्धरण का यह भी अर्थ है कि dicts और इस प्रकार चर असाइनमेंट भी CPython कार्यान्वयन विवरण के रूप में सुरक्षित है:

इसके बाद, पैकेज के लिए डॉक्सmultiprocessing समझाते हैं कि यह किस तरह से एक इंटरफ़ेस को उजागर करते समय स्पैनिंग प्रक्रिया द्वारा जीआईएल पर काबू पा लेता हैthreading :

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

और के लिए डॉक्सconcurrent.futures.ProcessPoolExecutor समझाने कि इसे इस्तेमाल करता है multiprocessingएक बैकेंड के रूप में:

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

अन्य आधार वर्ग के विपरीत किया जाना चाहिए जो ThreadPoolExecutorकि प्रक्रियाओं के बजाय धागे का उपयोग करता है

ThreadPoolExecutor एक Executor subclass है जो एसिंक्रोनस रूप से कॉल को निष्पादित करने के लिए थ्रेड्स के एक पूल का उपयोग करता है।

जिससे हम यह निष्कर्ष निकालते हैं कि ThreadPoolExecutorमैं केवल I / O बाध्य कार्यों के लिए उपयुक्त है, जबकि ProcessPoolExecutorCPU बाध्य कार्यों को भी संभाल सकता है।

निम्नलिखित प्रश्न पूछता है कि जीआईएल पहले स्थान पर क्यों मौजूद है: ग्लोबल इंटरप्रेटर लॉक क्यों?

प्रक्रिया बनाम धागा प्रयोग

पर Multiprocessing बनाम थ्रेडिंग अजगर मैं अजगर में धागे बनाम प्रक्रिया का एक प्रयोगात्मक विश्लेषण किया है।

परिणामों का त्वरित पूर्वावलोकन:

यहां छवि विवरण दर्ज करें


0

क्यों अजगर (CPython और अन्य) GIL का उपयोग करता है

से http://wiki.python.org/moin/GlobalInterpreterLock

CPython में, वैश्विक दुभाषिया लॉक या GIL, एक म्यूटेक्स है जो कई देशी धागों को एक बार में Python bytecodes को निष्पादित करने से रोकता है। यह ताला मुख्य रूप से आवश्यक है क्योंकि सीपीथॉन का मेमोरी प्रबंधन थ्रेड-सुरक्षित नहीं है।

इसे पायथन से कैसे हटाया जाए?

लूआ की तरह, शायद पायथन कई वीएम शुरू कर सकता है, लेकिन अजगर ऐसा नहीं करता है, मुझे लगता है कि कुछ अन्य कारण होने चाहिए।

Numpy या कुछ अन्य अजगर विस्तारित पुस्तकालय में, कभी-कभी, GIL को अन्य थ्रेड के लिए जारी करने से पूरे कार्यक्रम की दक्षता बढ़ सकती है।


0

मैं विजुअल इफेक्ट्स के लिए मल्टीथ्रेडिंग बुक से एक उदाहरण साझा करना चाहता हूं। इसलिए यहां क्लासिक डेड लॉक की स्थिति है

static void MyCallback(const Context &context){
Auto<Lock> lock(GetMyMutexFromContext(context));
...
EvalMyPythonString(str); //A function that takes the GIL
...    
}

अब अनुक्रम में घटनाओं पर विचार करें जिसके परिणामस्वरूप एक डेड-लॉक हुआ।

╔═══╦════════════════════════════════════════╦══════════════════════════════════════╗
    Main Thread                             Other Thread                         
╠═══╬════════════════════════════════════════╬══════════════════════════════════════╣
 1  Python Command acquires GIL             Work started                         
 2  Computation requested                   MyCallback runs and acquires MyMutex 
 3                                          MyCallback now waits for GIL         
 4  MyCallback runs and waits for MyMutex   waiting for GIL                      
╚═══╩════════════════════════════════════════╩══════════════════════════════════════╝
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.