2009-06-11 10 views
2

PygletにGUIアプリケーションを作成しており、インターネットから数十から数百のサムネイルを表示する必要があります。今、私はurllib.urlretrieveを使ってそれらをつかんでいますが、これは完了するまで毎回ブロックし、一度に1つしか取りません。PythonでノンブロッキングURLフェッチを行う方法

いつでもGUIをブロックすることなく、それらを並行してダウンロードし、終了後すぐに表示することをお勧めします。これを行う最善の方法は何ですか?

スレッドについてよくわかりませんが、threadingモジュールが役立つようですか?あるいは、私が見落とした簡単なやり方があるかもしれません。

答えて

3

おそらくthreadingまたはmultiprocessingモジュールの恩恵を受けるでしょう。あなたのいずれかがスレッドを使用する必要が

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

スレッドにはPoolに相当するものがありますか?これは別のプロセスを実行するように見えますが、必要以上に重いかもしれません。 – Kiv

+0

組み込みのものはないと思われますが、私はこれを見つけました:http://www.chrisarndt.de/projects/threadpool/これはかなり似ています。 – drdaeman

+0

ありがとう、スレッドプールはうまく動作しています。 – Kiv

2

疑いがあるように、これはスレッド処理に最適な状況です。 Hereは、私がPythonで自分の最初のスレッドを行うときに非常に役立つと思った短いガイドです。

2

あなたの言うとおり、いくつかのスレッドを作成して、それぞれがurlretrieve操作を実行することができます。これにより、メインスレッドは中断されずに続行できます。ここで

はPythonでスレッドについてのチュートリアルです: http://heather.cs.ucdavis.edu/~matloff/Python/PyThreads.pdf

+0

チュートリアルをいただきありがとうございました。 – Kiv

2

ここthreading.Threadを使用する方法の例です。あなたのクラス名を自分のクラス名で置き換えてください。スレッディングは、あなたのようなIO制限付きアプリケーションにとっては素晴らしいことであり、本当にスピードアップできることに注意してください。厳密にpythonスレッドを標準のPythonでの計算に使用するのは、一度に1つのスレッドしか計算できないので役に立ちません。

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

、またはTwistedなどの非同期ネットワーキング・ライブラリー:あなたは、実際に自分ですべてのものをThreadベースのクラスを作成する必要はありません、Pool.mapを使用して簡単な方法があります。私はあなたの特定のユースケースでスレッドを使用するほうが簡単かもしれないと思う。

1

あなたはこれらの選択肢があります。

  • スレッド:最も簡単なもののうまく
  • ツイストスケールしない:原因GILにメディア困難、うまくスケールが、株式のCPUとシングルスレッドであることを。
  • マルチプロセッシング:最も難しい。独自のイベントループを作成する方法がわかっている場合は、適切に拡張してください。

産業規模のフェッチャーが必要な場合を除き、スレッドを使用することをお勧めします。

関連する問題