2013-07-10 19 views
0

我環顧四周約線程開發很酷的簡單的網絡爬蟲,但它工作如此緩慢。python中的線程化:daemon.start()吃我爬蟲時間的20%。爲什麼?

下面是代碼片段我在ibm library發現:

urls = [] # huge list of urls 
    in_queue = Queue.Queue() 
    out_queue = Queue.Queue() 

    pool = ActivePool() 
    s = threading.Semaphore(semaphore) 

    for url in urls[:slice_size]: 
      in_queue.put(url) 
      t = ThreadUrl(pool, s, url, in_queue, out_queue) 
      t.setDaemon(True) 
      t.start() 

    counter = slice_size 
    while not in_queue.empty() or not out_queue.empty(): 
      speed_new_daemon = time.time() 
      url = urls[counter] 
      in_queue.put(url) 
      t = ThreadUrl(pool, s, url, in_queue, out_queue) 
      t.setDaemon(True) 

      t.start()  # <------ why 20% of all time I lose here? 

      counter += 1 
      speed_new_daemon = time.time() - speed_new_daemon 

      speed_parser = time.time() 
      result = out_queue.get() 
      my_parser(result) 
      speed_parser = time.time() - speed_parser 

      # speed_parser only 80%, when speed_new_daemon takes 20%... 
    in_queue.join() 
+0

多線程代碼是很難的個人資料。你是如何衡量這一點的? –

+0

這不是來自鏈接文檔的代碼。 – abarnert

+0

此外,您的標題引用的行不在您的源代碼或IBM中。 – abarnert

回答

4

IBM的文檔你報開始5個線程:

#spawn a pool of threads, and pass them queue instance 
for i in range(5): 
    t = ThreadUrl(queue) 
    t.setDaemon(True) 
    t.start() 

你的代碼是完全不同的。首先,它會創建每個URL一個線程池:

for url in urls[:slice_size]: 
    in_queue.put(url) 
    t = ThreadUrl(pool, s, url, in_queue, out_queue) 
    t.setDaemon(True) 
    t.start() 

然後它繼續通過主環路創建新線程每次:

while not queue.empty() or not out_queue.empty(): 
     speed_start_new_daemon = time.time() 
     url = urls[counter] 
     in_queue.put(url) 
     t = ThreadUrl(pool, s, url, in_queue, out_queue) 
     t.setDaemon(True) 

所以最終,你將有一個噸的線程。由於所有這些線程僅爭取幾個內核,每個線程都將花費大部分時間在等待。最重要的是,你最終會給調度器帶來壓力,所以你的CPU將花費大量的時間來試圖找出如何運行你的線程。

同時,啓動1000個線程可能不會佔用太多的CPU時間,但是下載1000個URL也不會佔用太多的CPU時間(它是I/O限制的,而不是處理器限制的),所以...您希望在哪裏CPU使用率集中?

+0

我期望在my_parser(結果)中,但它只佔空閒時間的80%。我需要99% – stackterminator

+0

99% 100% – stackterminator

+0

好吧,你永遠不能有100%的CPU,除非你寫OS少嵌入式代碼,你當然不可能有100%的CPU,如果你使用OS線程。此外,使用更多的CPU並不佔有優勢,這是一個_cost_,如果它實際上使你的代碼運行速度更快,這是一個很好的折衷,只是用它來使用它是愚蠢的緣故。無論如何,我的回答已經解釋了你的問題。修復它,你的代碼將變得更快。 – abarnert