[英]How to do a non-blocking URL fetch in Python
我正在Pyglet中編寫一個GUI應用程序,它必須顯示來自Internet的數十到數百個縮略圖。 現在,我正在使用urllib.urlretrieve抓住它們,但每次都會阻塞它們,直到它們完成,並且一次只抓取一個。
我寧願並行下載它們,並且每完成一次就會顯示它們,而不會在任何時候阻止GUI。 做這個的最好方式是什么?
我對線程知之甚少,但看起來線程模塊可能有幫助嗎? 或者也許有一些我忽略的簡單方法。
您可能會受益於threading
或多multiprocessing
模塊。 您實際上並不需要自己創建所有這些基於Thread
的類,使用Pool.map
有一個更簡單的方法:
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)
如您所料,這是線程的完美情況。 這是一個簡短的指南,我發現在python中進行我自己的第一次線程時非常有幫助。
正如您所指出的那樣,您可以創建多個線程,每個線程都負責執行urlretrieve操作。 這允許主線程不間斷地繼續。
這是python中的線程教程: http : //heather.cs.ucdavis.edu/~matloff/Python/PyThreads.pdf
這是一個如何使用threading.Thread的例子。 只需用您自己的類名替換類名和自己的run函數。 請注意,線程對於像您這樣的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
你有這些選擇:
我建議只使用線程,除非你需要一個工業規模的提取器。
您需要使用線程,或者使用Twisted之類的異步網絡庫。 我懷疑在您的特定用例中使用線程可能更簡單。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.