2009-06-11 57 views
2

我正在編寫一個Pyglet的GUI應用程序,它必須從互聯網上顯示數十到數百個縮略圖。現在,我使用urllib.urlretrieve來抓住它們,但是每次都會阻止它們,直到它們完成,並且一次只抓取一個。如何在Python中進行無阻塞的URL提取

我寧願並行下載它們,並在每一個完成後立即顯示它們,而不會在任何時候阻塞GUI。做這個的最好方式是什麼?

我對線程瞭解不多,但看起來像threading模塊可能有幫助嗎?或者也許有一些我忽略的簡單方法。

回答

3

你可能會從threadingmultiprocessing模塊中受益。你實際上並不需要自己創造那些Thread基類,有使用Pool.map一個更簡單的方法:異步聯網庫如Twisted

from multiprocessing import Pool 

def fetch_url(url): 
    # Fetch the URL contents and save it anywhere you need and 
    # return something meaningful (like filename or error code), 
    # if you wish. 
    ... 

pool = Pool(processes=4) 
result = pool.map(f, image_url_list) 
+0

線程池是否存在等價物?這看起來像運行單獨的進程,可能比我需要的更重。 – Kiv 2009-06-12 00:04:09

2

正如你懷疑的那樣,這是一個線程完美的情況。 Here是一個簡短的指南,我發現在python中執行我自己的第一個線程時非常有幫助。

2

這裏有一個如何使用threading.Thread的例子。只需用你自己的和運行函數替換你的類名。請注意,線程對於您的IO限制應用程序非常有用,並且可以加快速度。在標準python中嚴格使用pythong線程進行計算並不會有幫助,因爲一次只能有一個線程計算。

import threading, time 
class Ping(threading.Thread): 
    def __init__(self, multiple): 
     threading.Thread.__init__(self) 
     self.multiple = multiple 
    def run(self): 
     #sleeps 3 seconds then prints 'pong' x times 
     time.sleep(3) 
     printString = 'pong' * self.multiple 

pingInstance = Ping(3) 
pingInstance.start() #your run function will be called with the start function 
print "pingInstance is alive? : %d" % pingInstance.isAlive() #will return True, or 1 
print "Number of threads alive: %d" % threading.activeCount() 
#main thread + class instance 
time.sleep(3.5) 
print "Number of threads alive: %d" % threading.activeCount() 
print "pingInstance is alive?: %d" % pingInstance.isAlive() 
#isAlive returns false when your thread reaches the end of it's run function. 
#only main thread now 
0

您可能需要使用線程,或。我懷疑在特定的用例中使用線程可能會更簡單。

1

您有以下選擇:

  • 主題:最簡單的,但不能很好地擴展
  • 扭曲:中等難度,可很好但股價CPU由於GIL並且是單線程的。
  • 多處理:最難。如果你知道如何編寫自己的事件循環,可以很好地擴展。

我建議只使用線程,除非你需要工業規模的提取器。