2010-12-28 10 views
5

मेरे पास एक बहु-थ्रेडेड स्क्रिप्ट है जो कभी-कभी किसी सर्वर से कनेक्ट होने पर फ्रीज होती है लेकिन सर्वर कुछ भी वापस नहीं भेजता है। नेटस्टैट एक जुड़ा हुआ टीसीपी सॉकेट दिखाता है। यह तब भी होता है जब मेरे पास टाइमआउट सेट हो। टाइमआउट एक unthreaded स्क्रिप्ट में ठीक काम करता है। यहां कुछ नमूना कोड है।pycurl/curl CURLOPT_TIMEOUT विकल्प का पालन नहीं कर रहा है

def xmlscraper(url): 
    htmlpage = StringIO.StringIO() 
    rheader = StringIO.StringIO() 
    c = pycurl.Curl() 
    c.setopt(pycurl.USERAGENT, "user agent string") 
    c.setopt(pycurl.CONNECTTIMEOUT, 60) 
    c.setopt(pycurl.TIMEOUT, 120) 
    c.setopt(pycurl.FOLLOWLOCATION, 1) 
    c.setopt(pycurl.WRITEFUNCTION, htmlpage.write) 
    c.setopt(pycurl.HEADERFUNCTION, rheader.write) 
    c.setopt(pycurl.HTTPHEADER, ['Expect:']) 
    c.setopt(pycurl.NOSIGNAL, 1) 
    c.setopt(pycurl.URL, url) 
    c.setopt(pycurl.HTTPGET, 1) 

pycurl.global_init(pycurl.GLOBAL_ALL) 
for url in urllist: 
    t = threading.Thread(target=xmlscraper, args=(url,)) 
    t.start() 

किसी भी मदद की सराहना की जाएगी! कुछ हफ्तों के लिए इसे हल करने की कोशिश कर रहा है।

संपादित करें: यूआरएलिस्ट के पास लगभग 10 यूआरएल हैं। यह कोई फर्क नहीं पड़ता कि कितने हैं।

संपादन 2: मैंने अभी इस कोड का परीक्षण नीचे किया है। मैंने एक PHP स्क्रिप्ट का उपयोग किया जो 100 सेकंड तक सोता है।

import threading 
import pycurl 
def testf(): 
    c = pycurl.Curl() 
    c.setopt(pycurl.CONNECTTIMEOUT, 3) 
    c.setopt(pycurl.TIMEOUT, 6) 
    c.setopt(pycurl.NOSIGNAL, 1) 
    c.setopt(pycurl.URL, 'http://xxx.xxx.xxx.xxx/test.php') 
    c.setopt(pycurl.HTTPGET, 1) 
    c.perform() 
t = threading.Thread(target=testf) 
t.start() 
t.join() 

उस कोड में Pycurl ठीक समय पर लगता है। तो मुझे लगता है कि इसमें यूआरएल की संख्या के साथ कुछ करना है? जीआईएल?

edit3:

मुझे लगता है कि यह libcurl ही कभी कभी के कारण जब मैं जाँच स्क्रिप्ट libcurl अभी भी अंत पर घंटे के लिए एक सर्वर से कनेक्ट है के साथ क्या करना पड़ सकता है। यदि pycurl ठीक से समय समाप्त हो रहा था तो सॉकेट बंद कर दिया गया होगा।

+0

कितने यूआरएल urllist में आती है जब यह समस्या तब होती है? क्या यह अभी भी केवल एक (या कुछ) यूआरएल/धागे के साथ होता है? –

+0

यदि आप अपने 'edit2' कोड का उपयोग करके एकाधिक थ्रेड शुरू करते हैं, तो क्या वे प्रत्येक टाइमआउट सही तरीके से करते हैं? –

+0

हाँ वे ठीक काम करते हैं। इसे दो सौ पंजे वाले थ्रेड के साथ बाहर निकाला और सभी ठीक से बाहर निकल गए। – Incognito

उत्तर

3

मैं अपने 'EDIT2' कोड को संशोधित अधिक थ्रेड अंडे देने के लिए और यह (पायथन 2.6.6 के साथ उबंटू 10.10) मेरे मशीन पर ठीक काम करता है

import threading 
import pycurl 

def testf(): 
    c = pycurl.Curl() 
    c.setopt(pycurl.CONNECTTIMEOUT, 3) 
    c.setopt(pycurl.TIMEOUT, 3) 
    c.setopt(pycurl.NOSIGNAL, 1) 
    c.setopt(pycurl.URL, 'http://localhost/cgi-bin/foo.py') 
    c.setopt(pycurl.HTTPGET, 1) 
    c.perform() 

for i in range(100): 
    t = threading.Thread(target=testf) 
    t.start() 

मैं 100 थ्रेड और सभी टाइमआउट 3 सेकंड (जैसे मैंने निर्दिष्ट) पर बढ़ा सकता है।

मैं अभी तक जीआईएल और धागा विवाद पर आरोप लगा :) जाना नहीं होता

1

ग्लोबल इंटरप्रेटर लॉक ("जीआईएल") द्वारा कुछ स्थितियों में पाइथन थ्रेड हैंमस्ट्रंग हैं। ऐसा हो सकता है कि आपके द्वारा शुरू किए जा रहे थ्रेड समय समाप्त नहीं हो रहे हैं क्योंकि वे वास्तव में पर्याप्त रूप से पर्याप्त नहीं चल रहे हैं।

यह related StackOverflow question सही दिशा में इंगित कर सकता है:

+0

जो मैं समझता हूं उससे जीआईएल केवल पाइथन कोड को प्रभावित करता है। मैं pycurl बस libcurl करने के लिए सबकुछ सौंपने के लिए समझ गया और यह खुद टाइमआउट को संभाला। – Incognito

+0

हालांकि जीआईएल पाइथन थ्रेडिंग को प्रभावित करता है। संबंधित प्रश्न की जांच करें। –

+0

कुछ यूआरएल को कुकीज़ की आवश्यकता है ताकि मैं cookielib का उपयोग नहीं कर सकूं। अन्यथा मैं urllib2 के साथ अटक गया होगा। – Incognito

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