2013-07-30 12 views
5

के लिए आउटपुट कारण मेरे पास एक ऐसा एप्लिकेशन है जो प्रत्येक कुछ मिनटों में सर्वरों का एक गुच्छा चुनाव करता है। ऐसा करने के लिए, यह सर्वर प्रति एक धागा मतदान पर (15 सर्वरों) spawns और एक वस्तु के लिए डेटा वापस लिखते हैं:पायथन क्रैश

import requests 

class ServerResults(object): 
    def __init__(self): 
     self.results = [] 

    def add_server(some_argument): 
     self.results.append(some_argument) 

servers = ['1.1.1.1', '1.1.1.2'] 
results = ServerResults() 

for s in servers: 
    t = CallThreads(poll_server, s, results) 
    t.daemon = True 
    t.start() 

def poll_server(server, results): 
    response = requests.get(server, timeout=10) 
    results.add_server(response.status_code); 

CallThreads वर्ग एक सहायक समारोह एक समारोह (कॉल करने के लिए तर्क के साथ इस मामले poll_server() में है (इस मामले में s और results), आप Python utility functions के मेरे गीथब रेपो में स्रोत देख सकते हैं। अधिकांश समय यह ठीक काम करता है, हालांकि कभी-कभी एक धागा अंतराल से लटकता है। मुझे यकीन नहीं है कि क्यों, मैं इसका उपयोग कर रहा हूं जीईटी अनुरोध पर टाइमआउट। किसी भी मामले में, अगर थ्रेड लटकता है तो लटका धागे घंटों या दिनों के दौरान बनते हैं, और फिर पायथन क्रैश हो जाता है:

File "/usr/lib/python2.7/threading.py", line 495, in start 
    _start_new_thread(self.__bootstrap,()) 
thread.error: can't start new thread 

Exception in thread Thread-575 (most likely raised during interpreter shutdown) 
Exception in thread Thread-1671 (most likely raised during interpreter shutdown) 
Exception in thread Thread-831 (most likely raised during interpreter shutdown) 

मैं इससे कैसे निपट सकता हूं? ऐसा लगता है कि killablockingthreadinPython कोई रास्ता नहीं है। इस एप्लिकेशन को रास्पबेरी पीआई पर चलाने की जरूरत है, इसलिए twisted जैसी बड़ी लाइब्रेरी फिट नहीं होंगी, असल में मुझे requests लाइब्रेरी से छुटकारा पाना होगा!

+0

सबसे पहले, यह एक पीआई पर है जब यह लटकता है, या आप कहीं और परीक्षण कर रहे हैं? प्लेटफ़ॉर्म-विशिष्ट टूल हो सकते हैं जो थ्रेड कर रहे हैं यह देखने में मदद करेंगे, लेकिन आपने अपना प्लेटफ़ॉर्म निर्दिष्ट नहीं किया है। – Useless

+0

दूसरा, 'अनुरोध' क्या है?इसे देखे बिना, यह कहना असंभव है कि – Useless

+0

में दौड़ की स्थिति है, तीसरा, भले ही आप एक थ्रेड में सिंक्रोनस गैर-अवरुद्ध I/O का उपयोग न करें, – Useless

उत्तर

4

जहां तक ​​मैं कह सकता हूं, संभव परिदृश्य यह है कि जब किसी दिए गए सर्वर के लिए थ्रेड "लटकता" होता है, तो यह वहां "हमेशा" रहेगा। अगली बार जब आप अपने सर्वर से पूछते हैं तो एक और धागा उत्पन्न होता है (_start_new_thread), उस बिंदु तक जहां पायथन क्रैश हो जाता है।

शायद

नहीं अपने (मुख्य) समस्या है, लेकिन आपको:

  • एक धागा पूल का उपयोग - यह अपने अपने सिस्टम से सीमित संसाधनों नई धागे बार-बार उत्पन्न करने के रूप में के रूप में ज्यादा तनाव नहीं होगा ।
  • जांचें कि आप results पर समवर्ती पहुंच को संभालने के लिए "थ्रेड-संगत" तंत्र का उपयोग करते हैं। शायद semaphore या mutex से लॉक आपके कोड के परमाणु भाग। शायद queue जैसे एक समर्पित डेटा संरचना होगी।

के संबंध में "लटका" से प्रति - सावधान रहना है कि टाइमआउट तर्क जबकि (urlopen) कनेक्शन स्थापित करने के लिए समय समाप्ति से संबंधित है "एक यूआरएल को खोलने"। नहीं वास्तविक डेटा डाउनलोड करने के लिए:

वैकल्पिक टाइमआउट पैरामीटर कनेक्शन का प्रयास की तरह अवरुद्ध कार्यों के लिए सेकंड में एक समय समाप्ति निर्दिष्ट करता है (यदि निर्दिष्ट नहीं है, वैश्विक डिफ़ॉल्ट टाइमआउट सेटिंग का उपयोग किया जाएगा)। यह वास्तव में HTTP, HTTPS और FTP कनेक्शन के लिए केवल काम करता है।

+0

धन्यवाद। असल में, मुझे पता है कि टाइमआउट केवल कनेक्शन के लिए है, 'अनुरोध' डाउनलोड के समय के लिए एक रास्ता प्रकट करने के लिए प्रतीत नहीं होता है। मुझे प्रति थ्रेड के एक थ्रेड का विचार पसंद है, लेकिन जब थ्रेड लटकता है, तो प्रश्न में सर्वर अब मतदान नहीं किया जाएगा। – dotancohen

+0

@ डॉटनकोहेन न तो urllib2 अनुरोध सॉकेट ऑब्जेक्ट का खुलासा करने का अनुरोध नहीं करता है। इसलिए, आपको शायद [socket.setdefaulttimeout] (http://docs.python.org/2/library/socket.html#socket.setdefaulttimeout) I/O ऑपरेशन टाइमआउट को ठीक करने के लिए * आपके कनेक्शन को खोलने से ठीक पहले (और शायद इसे बाद में रीसेट कर रहा है)। थ्रेड पूल के उपयोग के बारे में, मेरा * अनुमान * था जब कोई सर्वर किसी थ्रेड से आने वाले अनुरोध को अवरुद्ध करता है तो यह कनेक्ट करने के बाद के सभी प्रयासों को अवरुद्ध कर देगा। लेकिन हो सकता है कि धागे "यादृच्छिक" हों? –

+0

धन्यवाद सिल्वेन, मैं सॉकेट टाइमआउट पर एक नज़र डालेगा। अच्छा लगता है! सर्वर बाद के कनेक्शन की अनुमति देते हैं, अन्यथा निम्नलिखित थ्रेड उन्हें मतदान करने में असफल हो जाएंगे। मैं वास्तव में नहीं जानता कि लटकने का कारण क्या है या यहां तक ​​कि इसे डीबग करना शुरू करना है। – dotancohen

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