2012-11-10 95 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服務器,可能不是一件非常友善的事情。確保保持在服務範圍內。