2011-12-24 36 views
28

है मैं अजगर धागे के बारे में कई प्रश्न हैं।क्या एक अजगर धागा

  1. क्या पाइथन थ्रेड एक पायथन या ओएस कार्यान्वयन है? एक ही स्मृति की खपत, एक ही आदेश है लेकिन एक अलग पीआईडी ​​-
  2. जब मैं htop का प्रयोग कर एक मल्टी-थ्रेडेड स्क्रिप्ट कई प्रविष्टियाँ है। क्या इसका मतलब यह है कि एक [पायथन] धागा वास्तव में एक विशेष प्रकार की प्रक्रिया है? (मैं जानता हूँ कि htop में एक सेटिंग एक प्रक्रिया के रूप में इन धागों को दिखाने के लिए है - Hide userland threads)
  3. Documentation का कहना है:

एक धागा एक "डेमॉन सूत्र" के रूप में चिह्नित किया जा सकता है। इस ध्वज का महत्व यह है कि पूरे पायथन प्रोग्राम निकलता है जब केवल डेमॉन थ्रेड शेष होते हैं।

मेरी व्याख्या/समझ थी: मुख्य धागा समाप्त हो जाता है जब सभी गैर-डिमन धागे समाप्त हो जाते हैं।

तो अजगर डेमॉन धागे अजगर कार्यक्रम का हिस्सा है, तो "पूरे अजगर कार्यक्रम बाहर निकलता है जब केवल डेमॉन धागे छोड़ दिया जाता है" नहीं कर रहे हैं?

+0

आपका मतलब है 'थ्रेडिंग। थ्रेड' सही? –

+0

हाँ, मैं करता हूं। मानक पायथन में अन्य धागे हैं? – warvariuc

+0

हां, 'थ्रेड 'मॉड्यूल देशी धागे को एक और इंटरफ़ेस प्रदान करता है (लेकिन हे उसी मूल कार्यान्वयन का उपयोग करता है)। –

उत्तर

24
  1. अजगर धागे सभी कार्यान्वयन मुझे पता है (सी अजगर, PyPy और Jython) में ओएस धागे का उपयोग करके लागू। प्रत्येक पायथन धागे के लिए, एक अंतर्निहित ओएस धागा है।

  2. कुछ ऑपरेटिंग सिस्टम (लिनक्स उनमें से एक है) सभी चल रही प्रक्रियाओं की सूची में एक ही निष्पादन योग्य द्वारा लॉन्च किए गए सभी अलग-अलग धागे दिखाते हैं। यह ओएस का कार्यान्वयन विवरण है, पायथन के नहीं। कुछ अन्य ऑपरेटिंग सिस्टम पर, आप सभी प्रक्रियाओं को सूचीबद्ध करते समय उन धागे को नहीं देख सकते हैं।

  3. प्रक्रिया जब अंतिम गैर-डेमॉन धागा खत्म समाप्त कर देगा। उस बिंदु पर, सभी डेमॉन धागे समाप्त हो जाएंगे। तो, ये धागे आपकी प्रक्रिया का हिस्सा हैं, लेकिन इसे समाप्त करने से नहीं रोक रहे हैं (जबकि एक नियमित थ्रेड इसे रोक देगा)। यह शुद्ध पायथन में लागू किया गया है। एक प्रक्रिया समाप्त होती है जब सिस्टम _exit फ़ंक्शन को कॉल किया जाता है (यह सभी धागे को मार देगा), और जब मुख्य धागा समाप्त हो जाता है (या sys.exit कहा जाता है), पाइथन दुभाषिया जांचता है कि कोई अन्य गैर-डिमन थ्रेड चल रहा है या नहीं। यदि कोई नहीं है, तो यह _exit पर कॉल करता है, अन्यथा यह गैर-डिमन थ्रेड समाप्त होने की प्रतीक्षा करता है।


डेमॉन धागा झंडा शुद्ध पायथन में threading मॉड्यूल द्वारा कार्यान्वित किया जाता है। जब मॉड्यूल लोड होता है, तो Thread ऑब्जेक्ट मुख्य थ्रेड का प्रतिनिधित्व करने के लिए बनाया गया है, और यह _exitfunc विधि atexit हुक के रूप में पंजीकृत है।

इस समारोह का कोड है:

class _MainThread(Thread): 

    def _exitfunc(self): 
     self._Thread__stop() 
     t = _pickSomeNonDaemonThread() 
     if t: 
      if __debug__: 
       self._note("%s: waiting for other threads", self) 
     while t: 
      t.join() 
      t = _pickSomeNonDaemonThread() 
     if __debug__: 
      self._note("%s: exiting", self) 
     self._Thread__delete() 

इस समारोह अजगर दुभाषिया द्वारा कॉल किया जाएगा sys.exit कहा जाता है, या मुख्य थ्रेड समाप्त हो जाता है जब। जब फ़ंक्शन वापस आता है, तो दुभाषिया सिस्टम _exit फ़ंक्शन को कॉल करेगा। और फ़ंक्शन समाप्त हो जाएगा, जब केवल डेमॉन थ्रेड चल रहे हों (यदि कोई हो)।

जब _exit फ़ंक्शन कहा जाता है, तो ओएस सभी प्रक्रिया धागे को समाप्त कर देगा, और फिर प्रक्रिया को समाप्त कर देगा। पाइथन रनटाइम _exit फ़ंक्शन को तब तक कॉल नहीं करेगा जब तक कि सभी गैर-डिमन थ्रेड किए जाते हैं।

सभी धागे प्रक्रिया का हिस्सा हैं।


मेरे व्याख्या/समझ थी: मुख्य थ्रेड समाप्त हो जाता है जब सभी गैर डेमॉन धागे समाप्त कर दिया जाता।

तो पाइथन डेमन थ्रेड पाइथन प्रोग्राम का हिस्सा नहीं हैं अगर "पूरे पायथन प्रोग्राम निकलता है जब केवल डेमॉन थ्रेड छोड़े जाते हैं"?

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

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


निम्नलिखित कार्यक्रम में मदद कर सकते डेमॉन धागा और नियमित रूप से धागा के बीच अंतर समझना:

import sys 
import time 
import threading 

class WorkerThread(threading.Thread): 

    def run(self): 
     while True: 
      print 'Working hard' 
      time.sleep(0.5) 

def main(args): 
    use_daemon = False 
    for arg in args: 
     if arg == '--use_daemon': 
      use_daemon = True 
    worker = WorkerThread() 
    worker.setDaemon(use_daemon) 
    worker.start() 
    time.sleep(1) 
    sys.exit(0) 

if __name__ == '__main__': 
    main(sys.argv[1:]) 

आप '--use_daemon' के साथ इस कार्यक्रम पर अमल करते हैं, तो आप देखेंगे कि कार्यक्रम केवल होगा Working hard लाइनों की एक छोटी संख्या मुद्रित करें। इस ध्वज के बिना, मुख्य थ्रेड खत्म होने पर भी प्रोग्राम समाप्त नहीं होगा, और प्रोग्राम Working hard लाइनों को तब तक मुद्रित करेगा जब तक कि यह मारे नहीं जाता है।

+0

> अंतिम गैर-डिमन थ्रेड खत्म होने पर प्रक्रिया समाप्त हो जाएगी। <तो, डेमॉन थ्रेड पाइथन अनुप्रयोग प्रक्रिया का हिस्सा नहीं हैं? मैंने सोचा कि एक डेमॉन और गैर-डिमन थ्रेड के बीच एकमात्र अंतर सिर्फ एक ध्वज है, जो निर्धारित करता है कि धागे का इलाज कैसे किया जाता है, जैसा कि दस्तावेज़ों में उल्लेख किया गया है:> इस ध्वज का महत्व यह है कि पूरे पायथन प्रोग्राम से निकलता है जब केवल डेमॉन थ्रेड बाकी है। <यहां 'संपूर्ण पायथन प्रोग्राम' क्या है? मैंने सोचा कि यह प्रक्रिया है। लेकिन जब प्रक्रिया में अभी भी धागे हैं तो प्रक्रिया को कैसे समाप्त किया जा सकता है? – warvariuc

+0

पाइथन में डेमॉन थ्रेड को कैसे कार्यान्वित किया गया है, यह बताने के लिए मेरा उत्तर अपडेट किया गया। –

+0

आपके धैर्य के लिए धन्यवाद। > जब '_exit' फ़ंक्शन कहा जाता है, तो ओएस सभी प्रक्रिया धागे को समाप्त कर देगा, और फिर प्रक्रिया को समाप्त कर देगा। <मुझे समझ में नहीं आ रहा है: आप कहते हैं कि '_exitfunc' को सभी धागे कहा जाता है, जिसमें डेमॉन वाले हैं, को ओएस समाप्त कर दिया जाएगा? यही वह नहीं है जो मैं देखता हूं - मुख्य थ्रेड समाप्त होने के बाद डेमॉन थ्रेड अभी भी चल रहे हैं। मेरे प्रश्नों में से एक यह है: कोई कैसे कह सकता है कि पाइथन _entire_ प्रोग्राम (प्रक्रिया) वहां से बाहर निकलता है अभी भी थ्रेड्स (डेमन) – warvariuc

3
  1. अजगर धागे व्यावहारिक रूप से, एक दुभाषिया कार्यान्वयन कर रहे हैं क्योंकि तथाकथित वैश्विक दुभाषिया ताला (जीआईएल), भले ही यह तकनीकी रूप से ओएस स्तर के सूत्रण तंत्र उपयोग कर रहा है। * Nix पर यह pthreads का उपयोग कर रहा है, लेकिन जीआईएल प्रभावी रूप से इसे अनुप्रयोग-स्तर थ्रेडिंग प्रतिमान में फंसे एक संकर बनाता है। तो आप इसे पीएस/टॉप आउटपुट में * निक्स सिस्टम पर कई बार देखेंगे, लेकिन यह अभी भी एक सॉफ्टवेयर-लागू थ्रेड की तरह (प्रदर्शन-वार) व्यवहार करता है।

  2. नहीं, आप बस अपने ओएस के अंतर्निहित थ्रेड कार्यान्वयन को देख रहे हैं। इस प्रकार का व्यवहार * निक्स पर्थ्रेड-जैसे थ्रेडिंग या आईएम द्वारा खुलासा किया गया है, यहां तक ​​कि खिड़कियां भी इस तरह से धागे को कार्यान्वित करती हैं।

  3. जब आपका प्रोग्राम बंद हो जाता है, तो यह सभी धागे को भी समाप्त करने की प्रतीक्षा करता है। यदि आपके पास धागे हैं, जो अनिश्चित रूप से बाहर निकलने को स्थगित कर सकते हैं, तो उन धागे को "डेमन्स" के रूप में फ़्लैग करना और आपके प्रोग्राम को समाप्त होने की अनुमति देना भी भले ही वे थ्रेड अभी भी चल रहे हों।

कुछ संदर्भ सामग्री आप रुचि हो सकती है:

+2

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

+0

हम इसके बारे में बहस कर सकते हैं। तथ्य यह है: (सी) पायथन सुविधा के बाहर अंतर्निहित थ्रेडिंग तंत्र का उपयोग कर रहा है (क्यों somethin reimplement, यह पहले से ही साबित हुआ है?), लेकिन आपको "वास्तविक" os-threads की गुड्स से इनकार करता है। तो ए) हां वे एक ओएस-स्तरीय थ्रेड तकनीकी हैं, लेकिन बी) नहीं, वे ओएस-स्तरीय धागे नहीं हैं, क्योंकि आप ओएस-स्तरीय धागे की साझा स्मृति के अलावा कोई भी लाभ नहीं प्राप्त करते हैं। यह भी है कि अगर आप अपने प्रदर्शन को बढ़ावा देने के लिए दिमाग में एक parrallelism है तो मैं उनका उपयोग करने की सलाह नहीं दूंगा। –

+0

एक बार एक बात थी, जिसमें दिखाया गया था कि संदर्भ-स्विचिंग के लिए अतिरिक्त परत की वजह से, कई धागे (बाहरी कार्यों के साथ भी कुछ दुर्लभ स्थितियों में) शुरू होने पर यह आपको काफी धीमा कर सकता है। एक बतख की तरह चलता है, तैरता है और quacks, भले ही यह एक बतख के रूप में पैदा नहीं हुआ था! ;-) –

10

मैं कार्यान्वयन से परिचित नहीं हूँ, इसलिए का एक प्रयोग करते हैं:

import threading 
import time 

def target(): 
    while True: 
     print 'Thread working...' 
     time.sleep(5) 

NUM_THREADS = 5 

for i in range(NUM_THREADS): 
    thread = threading.Thread(target=target) 
    thread.start() 
  1. थ्रेड की संख्या ps -o cmd,nlwp <pid> का उपयोग करके रिपोर्ट NUM_THREADS+1 (एक है मुख्य धागे के लिए अधिक), इसलिए जब तक ओएस उपकरण धागे की संख्या का पता लगाते हैं, तो उन्हें ओएस धागे होना चाहिए। मैंने cpython और jython दोनों के साथ प्रयास किया और, ज्योथन के बावजूद कुछ अन्य थ्रेड चल रहे हैं, प्रत्येक अतिरिक्त धागे जो मैं जोड़ता हूं, ps थ्रेड गिनती को एक से बढ़ाता है।

  2. मुझे htop व्यवहार के बारे में निश्चित नहीं है, लेकिन ps सुसंगत प्रतीत होता है।

  3. मैं धागे शुरू करने से पहले निम्न पंक्ति कहा: जब मैं CPython का उपयोग कर मार डाला

    thread.daemon = True 
    

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

नोट: मैं java1.6.0_23 पर अजगर के साथ उबंटू 11.10 2.7.2+ और Jython 2.2.1 इस्तेमाल किया

0

वहाँ प्रश्न के महान उत्तर दिए गए हैं, लेकिन मुझे लगता है डेमॉन धागे सवाल अब भी है एक साधारण फैशन में समझाया नहीं है। तो इस सवाल का जवाब सिर्फ तीसरा सवाल

को संदर्भित करता है "मुख्य थ्रेड समाप्त हो जाता है जब सभी गैर डेमॉन धागे समाप्त कर दिया जाता।"

तो अजगर डेमॉन धागे अजगर कार्यक्रम का हिस्सा है, तो "पूरे अजगर कार्यक्रम बाहर निकलता है जब केवल डेमॉन धागे छोड़ दिया जाता है" नहीं कर रहे हैं?

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

तो प्रोग्राम डेमॉन थ्रेड को समाप्त करने की प्रतीक्षा नहीं कर सकता है, क्योंकि ऐसा कभी नहीं हो सकता है। पाइथन प्रोग्राम को समाप्त कर देगा जब सभी गैर डिमन थ्रेड किए जाते हैं। यह डेमॉन थ्रेड को भी रोकता है।

डेमॉन थ्रेड तक प्रतीक्षा करने के लिए अपना काम पूरा कर लिया है, join() विधि का उपयोग करें। daemon_thread.join() पायथन को बाहर निकलने से पहले डेमॉन थ्रेड के लिए इंतजार कर देगा। join() भी टाइमआउट तर्क स्वीकार करता है।

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