Python でノンブロッキング URL フェッチを行う方法
-
13-09-2019 - |
質問
でGUIアプリを書いています ピグレット インターネットから数十から数百のサムネイルを表示する必要があります。今、私が使っているのは、 urllib.urlretrieve それらを取得しますが、これは完了するまで毎回ブロックされ、一度に 1 つだけ取得します。
それらを並行してダウンロードし、どの時点でも 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を使用する方法の例です。ちょうどあなた自身でクラス名と、独自での実行機能を交換してください。そのスレッドは、あなたのようなIO制限するアプリケーションのための素晴らしいですし、実際にそれをスピードアップすることができます。一度に1つのスレッドしか計算することができるので、助けていない標準の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
次の選択肢があります。
- スレッド:簡単だが拡張性が低い
- ツイスト:難易度は中程度で、スケールは良好ですが、GIL とシングルスレッドのため CPU を共有します。
- マルチプロセッシング:最も難しい。独自のイベント ループの作成方法を知っていれば、適切に拡張できます。
産業規模のフェッチャーが必要でない限り、スレッドのみを使用することをお勧めします。
あなたのどちらかは、そのようなツイストのようスレッド、または非同期ネットワーキング・ライブラリを使用する必要があります。私は、スレッドを使用すると、あなたの特定の使用の場合には単純であるかもしれないことを疑うます。