サーバーに接続するとフリーズすることがあるマルチスレッドスクリプトがありますが、サーバーは何も送り返しません。Netstatは、接続されたtcpソケットを示します。これは、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()
どんな助けでも大歓迎です!これを数週間解決しようとしています。
編集:URLリストには約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が適切にタイムアウトした場合、ソケットは閉じていたはずです。