2012-11-10 98 views
1

我有一个由ID组成的list,每天约50k。为什么我的线程停止?

,我必须每天进行50k的请求到服务器{服务器是在同一个城市},并获取信息,并将其存储到数据库中。我已经做了,使用loopThreads 和我“已经注意到时间未知时间后它停止的读取和存储...

看看我的代码片段

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的:它会继续打印多少号的左,在未知的时刻它停止打印并提取&存储

+0

'mysql.connector'定义''1''threadsafety'](http://www.python.org/dev/peps/pep-0249/#threadsafety),这意味着你不应该在没有同步的情况下在线程之间共享连接和游标。 – mata

+0

所以,我可以修改它吗? – Hamoudaq

+1

只是在'fetch'函数内移动'sql.connect'和'conn.cursor()' – mpaolini

回答

1

网络和线程都是非平凡的......最有可能的原因是一个网络事件,导致挂起的线程。我有兴趣听到人们是否有解决方案,因为我遇到了停止响应的线程问题。

但也有一些事情,我会在你的代码肯定改变:

  • 我永远不会赶上“异常”。只要记住那些你知道如何处理的例外。如果您的某个线程发生网络错误,您可以重试,而不是放弃该ID。
  • 代码中存在竞争条件:首先检查是否存在剩余内容,然后将其取出。在第二时间点,剩下的工作可能已经消失,导致一个例外。如果你觉得这个问题很难解决,那么就有一个很棒的python对象,它可以在线程之间传递对象,而不会出现竞争条件和死锁:Queue对象。一探究竟。
  • “睡眠(0.5)”对帮助一般不起作用。这不应该是必要的。这可能会降低竞争条件的可能性,但最好将竞赛条件完全排除在外。另一方面,如果有50个线程正在全力攻击Web服务器,可能不是一件非常友善的事情。确保保持在服务范围内。