あなたはPython 3.3を使用しているので、@ njzk2:concurrent.futures
によってリンクされたスレッドで見つからないstdlibソリューションをお勧めします。
これは、threading
またはmultiprocessing
プリミティブを直接処理するよりも高いレベルのインターステージです。プーリングと非同期レポートを処理するためのインターフェイスはExecutor
です。
ドキュメントは基本的には自分の状況に直接適用した例を持っているので、私はちょうどそれをここにドロップします:あなたがそう望む場合は、requests
呼び出しでurllib.request
呼び出しを置き換えることができます
import concurrent.futures
import urllib.request
URLS = #[some list of urls]
# Retrieve a single page and report the url and contents
def load_url(url, timeout):
conn = urllib.request.urlopen(url, timeout=timeout)
return conn.readall()
# We can use a with statement to ensure threads are cleaned up promptly
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
# Start the load operations and mark each future with its URL
future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}
for future in concurrent.futures.as_completed(future_to_url):
url = future_to_url[future]
try:
data = future.result()
# do json processing here
except Exception as exc:
print('%r generated an exception: %s' % (url, exc))
else:
print('%r page is %d bytes' % (url, len(data)))
。私は明らかな理由から、requests
が好きな傾向があります。
APIはちょっと変わっています。つまり、関数の非同期実行を表すFuture
オブジェクトを作りなさい。次に、Future
インスタンスに対してイテレータを与えるためにconcurrent.futures.as_completed
を使用します。それが完了すると、それが返されます。あなたの質問については
:
また、リクエスト数の関数として スレッドの最適な数を把握するための経験則があり、任意のはありますか?
ルールは、それはあなたのインターネット接続の速度を含む、あまりにも多くのものに依存します。私は実際にあなたが持っている要求の数に依存しない、より多くのハードウェアを実行していると言うでしょう。
幸いなことに、max_workers
kwargを調整して自分でテストするのはかなり簡単です。 5または10のスレッドから開始し、5ずつ増やしていく。ある時点では、パフォーマンスの低下が目立ち、スレッドの追加によるオーバーヘッドが増加した並列化の限界利益(ワード)を追い越し、 。
どのバージョンのpythonですか?あなたのstdlibオプションは2.7から3.3にかなり大幅に変更されます。 – roippi
私はurllib + Threadingモジュールを提案しようとしていましたが、リンクしたパッケージは基本的に同じことをしています。私のラップトップ(MacBook Pro、3.2 GHzプロセッサ、16 GB RAM)で問題なく、25個ほどのスレッドを実行しました。 – BenDundee
@roippi私はpythonを使用しています。3.3 –