私はマルチスレッドスクリプトを持っていますが、サーバに接続するときにフリーズすることがありますが、サーバは何も返信しません。 Netstatは、接続されたtcpソケットを表示します。これは、TIMEOUTが設定されていても発生します。タイムアウトは、スレッドのないスクリプトでうまくいきます。ここにいくつかのサンプルコードがあります。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()
ご協力いただければ幸いです。今これを数週間解決しようとしています。
編集: urllistには約10のURLがあります。どれくらいあるかは関係ありません。
edit2: 次のコードをテストしました。私は100秒間スリープするPHPスクリプトを使用しました。
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は正しくタイムアウトしているようです。だから私はそれが何かURLの数と関係があると思いますか? GIL?
EDIT3:
私はそれは私がスクリプトのlibcurlはまだ終わりで時間のためにサーバに接続されているチェック時に時々起こすのlibcurl自身で行う必要があるかもしれないと思います。もしpycurlが正しくタイムアウトしていれば、ソケットは閉じられているでしょう。
この問題が発生した場合、いくつのURLがurllistにありますか?それはまだ1つ(または少数)のURL /スレッドだけで起こりますか? –
'edit2'コードを使用して複数のスレッドを開始する場合は、タイムアウトが正しく行われますか? –
ええ、彼らは正常に動作します。数百の生まれのスレッドで試してみて、すべてタイムアウトしました。 – Incognito