2009-04-30 15 views
9

मेरे पास एक थ्रेड है जो पंक्तियों को self.output में जोड़ता है और एक लूप जो चलता है जब तक self.done सत्य नहीं होता है (या अधिकतम निष्पादन समय तक पहुंच जाता है)।पायथन - थ्रेडिंग और एक जबकि ट्रू लूप

क्या थोड़ी देर के लूप का उपयोग करने के अलावा ऐसा करने का एक और अधिक प्रभावी तरीका है जो लगातार यह देखने के लिए जांच करता है कि यह किया गया है या नहीं। जबकि पाश के चलते समय सीपीयू 100% करने के लिए स्पाइक का कारण बनता है ..

time.clock() 
while True: 

    if len(self.output): 
     yield self.output.pop(0) 

    elif self.done or 15 < time.clock(): 
     if 15 < time.clock(): 
      yield "Maximum Execution Time Exceeded %s seconds" % time.clock() 
     break 

उत्तर

11

क्या आपके धागे स्वयं को मुख्य रूप से स्वयं .output में जोड़ रहे हैं, आपके मुख्य कार्य को उनका उपभोग करते हुए? यदि ऐसा है, तो यह Queue.Queue के लिए एक दर्जी निर्मित नौकरी है।

import Queue 

# Initialise queue as: 
queue = Queue.Queue() 
Finished = object() # Unique marker the producer will put in the queue when finished 

# Consumer: 
try: 
    while True: 
     next_item = self.queue.get(timeout=15) 
     if next_item is Finished: break 
     yield next_item 

except Queue.Empty: 
    print "Timeout exceeded" 

आपका निर्माता धागे के साथ queue.put(item)

[संपादित करें] कतार में आइटम जोड़ने जब self.done (उदाहरण के एक से अधिक आइटम के लिए जाँच मूल कोड एक दौड़ मुद्दा है: अपने कोड कुछ की तरह हो जाना चाहिए फ्लैग सेट होने से पहले कतार में जोड़ा जा सकता है, जिससे कोड पहले को जमानत दे सकता है)। ΤΖΩΤΖΙΟΥ से एक सुझाव के साथ अद्यतन - उत्पादक धागे को इसके बाद एक विशेष टोकन (समाप्त) कतार में जोड़ना चाहिए ताकि यह संकेत मिलता है कि यह पूरा हो गया है।

नोट: यदि आपके पास एकाधिक उत्पादक धागे हैं, तो आपको यह पूरा करने के लिए एक और सामान्य दृष्टिकोण की आवश्यकता होगी कि वे कब समाप्त हो जाएं।आप इसे एक ही रणनीति के साथ पूरा कर सकते हैं - प्रत्येक थ्रेड एक फिनिश मार्कर होता है और जब उपभोक्ता num_threads मार्कर देखता है तो उपभोक्ता समाप्त हो जाता है।

+0

ओओयूओ, अब हम बात कर रहे हैं। : डी – Ian

+0

क्या कोई समय सीमा के बिना एक Queue.get() पर थ्रेड अवरुद्ध करने का कोई तरीका है कि निर्माता धागे में कुछ भी डाल रहा है ताकि यह साफ से बाहर निकल सके? – millimoose

+0

@ एसआईआई: जब आप इसे बनाते हैं तो आप थ्रेड डिमनिक को चिह्नित कर सकते हैं। इसका मतलब है कि जब आपका प्रोग्राम निकलता है तो थ्रेड बाहर निकल जाएगा। –

0

उपयोग time.sleep (सेकंड) जबकि पाश cpu त्यागना से प्रत्येक यात्रा के बाद एक संक्षिप्त ठहराव बनाने के लिए। आपको प्रत्येक पुनरावृत्ति के दौरान सोने का समय निर्धारित करना होगा, यह कितना महत्वपूर्ण है कि आप इसे पूरा करने के तुरंत बाद नौकरी पकड़ लें।

उदाहरण:

time.clock() 
while True: 

    if len(self.output): 
     yield self.output.pop(0) 

    elif self.done or 15 < time.clock(): 
     if 15 < time.clock(): 
      yield "Maximum Execution Time Exceeded %s seconds" % time.clock() 
      break 

    time.sleep(0.01) # sleep for 10 milliseconds 
+0

नींद आमतौर पर खराब प्रदर्शन में परिणाम देती है। आपको नींद का उपयोग करने से पहले सिंक्रनाइज़ेशन पर विचार करना चाहिए। – Francis

0

आप यहाँ एक तुल्यकालन आदिम उपयोग करना होगा। यहां देखें: http://docs.python.org/library/threading.html

घटना वस्तुएं बहुत सरल लगती हैं और आपकी समस्या का समाधान करना चाहिए। आप एक शर्त ऑब्जेक्ट या सेमफोर का भी उपयोग कर सकते हैं।

मैं एक उदाहरण पोस्ट नहीं करता क्योंकि मैंने कभी भी ईवेंट ऑब्जेक्ट्स का उपयोग नहीं किया है, और विकल्प शायद कम सरल हैं।


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

0

उपयोग म्युटेक्स मॉड्यूल या घटना/सेमाफोर

1

एक सेमाफोर का प्रयोग करें; कार्य पूरा होने पर काम करने वाले थ्रेड को रिलीज़ करें, और जब तक कार्यकर्ता सैमफोर के साथ समाप्त न हो जाए तब तक अपने संलग्न थ्रेड को अवरुद्ध करें।

यानी। कार्यकर्ता में, काम की शुरुआत में self.done = threading.Semaphore() जैसे कुछ और self.done.release() समाप्त होने पर कुछ करें। व्यस्त लूप की बजाय ऊपर दिए गए कोड में, बस self.done.acquire() करें; जब कार्यकर्ता धागा समाप्त हो जाता है, तो नियंत्रण वापस आ जाएगा।

संपादित करें: मुझे डर है कि मैं आपके आवश्यक टाइमआउट मान को संबोधित नहीं करता हूं; यह issue मानक पुस्तकालय में एक सेमफोर टाइमआउट की आवश्यकता का वर्णन करता है।

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