1

我有一个list由ID组成的,每天大约50k。

我必须每天向服务器发出 50k 请求{服务器在同一个城市},然后获取信息并将其存储到数据库中......我已经使用loop并且Threads 我注意到在未知时期之后时间它停止获取和存储......

看看我的代码片段

import re,urllib,urllib2
import mysql.connector as sql
import threading
from time import sleep
import idvalid

conn = sql.connect(user="example",password="example",host="127.0.0.1",database="students",collation="cp1256_general_ci")
cmds = conn.cursor()

ids=[] #here is going to be stored the ID's

def fetch():
    while len(ids)>0:#it will loop until the list of ID's is finish 
        try:
            idnumber = ids.pop()
            content = urllib2.urlopen("http://www.example.com/fetch.php?id="+idnumber,timeout=120).read()
            if content.find('<font color="red">') != -1:
                    pass
            else:
                    name=content[-20:]
                    cmds.execute("INSERT INTO `students`.`basic` (`id` ,`name`)VALUES ('%s', '%s');"%(idnumber,name))
        except Exception,r:
            print r,"==>",idnumber
            sleep(0.5)#i think sleep will help in threading ? i'm not sure
            pass
        print len(ids)#print how many ID's left

for i in range(0,50):#i've set 50 threads
    threading.Thread(target=fetch).start()

output:它将继续打印剩余的 ID 数量,并在未知的时刻停止打印、获取和存储

4

1 回答 1

1

网络和线程都不是微不足道的......最有可能的原因是导致线程挂起的网络事件。我很想知道人们是否对此有解决方案,因为我遇到了同样的线程停止响应的问题。

但是我肯定会在您的代码中更改一些内容:

  • 我永远不会抓住“异常”。只需捕获那些您知道如何处理的异常。如果您的一个线程中发生网络错误,您可以重试而不是放弃 id。
  • 您的代码中有一个竞争条件:您首先检查是否有剩余内容,然后将其取出。在第二个时间点,剩余的工作可能已经消失,导致异常。如果您发现这很难解决,有一个出色的 python 对象,它可以在线程之间传递对象而不会出现竞争条件和死锁:Queue 对象。一探究竟。
  • “睡眠(0.5)”一般不会帮助线程。应该没有必要。它可能会减少遇到竞态条件的机会,但最好将竞态条件完全编程出来。另一方面,让 50 个线程全速攻击 Web 服务器可能不是一件非常友好的事情。确保保持在服务可以提供的范围内。
于 2012-11-10T16:11:04.310 回答