Ho uno script multi-thread che si blocca occasionalmente quando si collega a un server ma il server non invia nulla indietro. Netstat mostra una presa tcp collegata. Questo succede anche se ho impostato TIMEOUT. Il timeout funziona bene in uno script non leggibile. Ecco alcuni esempi di codice.pycurl/curl non seguendo l'opzione 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()
Qualsiasi aiuto sarebbe molto apprezzato! ho cercato di risolvere questo problema per qualche settimana.
modifica: L'urllist ha circa 10 URL. Non sembra importare quanti ce ne sono.
edit2: Ho appena testato questo codice di seguito. Ho usato uno script php che dorme per 100 secondi.
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 in questo codice sembra scadere correttamente. Quindi immagino che abbia qualcosa a che fare con il numero di URL? GIL?
Edit3:
penso che potrebbe avere a che fare con libcurl stessa causa a volte quando controllo il libcurl script è ancora connesso a un server per ore e ore. Se pycurl fosse scaduto correttamente, la presa sarebbe stata chiusa.
quanti URL sono in urllist quando si verifica questo problema? si verifica ancora con solo un singolo (o pochi) URL/thread? –
se si avviano più thread utilizzando il proprio codice 'edit2', vengono eseguiti correttamente ogni timeout? –
sì, funzionano bene. Ho provato con un paio di centinaia di thread generati e tutto è scaduto correttamente. – Incognito