2010-12-28 16 views
5

Bir sunucuya bağlandığında bazen donuyor, ancak sunucu herhangi bir şey göndermiyorsa çok iş parçacıklı bir komut dosyası var. Netstat bağlı bir tcp soketini gösterir. Bu, TIMEOUT ayarlanmış olsa bile olur. Zaman aşımı, işlenmemiş bir komut dosyasında düzgün çalışıyor. İşte bazı örnek kod.CURLOPT_TIMEOUT seçeneğini takip etmeyen pazı/kıvrılma

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() 

Herhangi bir yardım çok takdir edilecektir! Bunu birkaç hafta için çözmeye çalışıyordum.

düzenleme: Urllist yaklaşık 10 url'ye sahiptir. Kaç tane olduğu önemli değil.

edit2: Sadece bu kodu aşağıda test ettim. 100 saniye boyunca uyuyan bir php betiği kullandım. Bu koddaki Pycurl, zaman aşımına uğramış gibi görünüyor. Yani sanırım URL'lerin sayısı ile ilgili bir şey var mı? GIL?

Edit3:

Ben Senaryonun libcurl hala saatlerce bir sunucuya bağlı olduğunu gösterirse kendisi bazen neden libcurl ile ilgisi olabileceğini düşünüyorum. Eğer püskül düzgün zaman aşımına uğradıysa, o zaman soket kapatılmış olur.

+0

? Hala tek bir (veya birkaç) urls/thread ile olur mu? –

+0

'edit2' kodunuzu kullanarak birden çok ileti dizisi başlatırsanız, her bir zaman aşımı düzgün yapar mı? –

+0

evet iyi çalışıyorlar. Birkaç yüz yumurtlama ipliği ile denedim ve hepsi doğru şekilde zamanlandı. – Incognito

cevap

3

ve

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() 
(Python 2.6.6 ile Ubuntu 10.10) benim makine üzerinde çalışıyor

100 iş parçacığı ve tüm zaman aşımlarını 3 saniyede oluşturabilirim (belirttiğim gibi).

Henüz GiL ve iplik çekişme suçlamaya :) gitmezdim Bu sorun oluştuğunda URLlist kaç URL'ler

1

Python dizileri, bazı durumlarda Küresel Tercüman Kilidi ("GIL") tarafından engellenir. Başladığınız iş parçacıklarının zaman aşımına uğraması olmayabilir çünkü aslında yeterince sık çalıştırılmıyorlar.

Bu related StackOverflow question doğru yönde bir işaret olabilir: Birden fazla konuları yumurtlamaya için 'edit2' kod modifiye

+0

anladığım kadarıyla GIL sadece python kodunu etkiler. Pycurl'in her şeyi libcurl'e teslim etmesini anladım ve zaman aşımına uğradı. – Incognito

+0

GIL, Python iş parçacığını etkiler. İlgili soruyu kontrol edin. –

+0

Bazı URL'lerin çerezlere ihtiyacı var, bu yüzden cookielib kullanamıyorum. Aksi takdirde urllib2 ile sıkışmış olurdu. – Incognito

İlgili konular