2016-11-16 5 views
0

私は次のコードを持っている:実際のダウンロードタスクが非同期的に継続しながら、ThreadPoolExecutorコールバック?

from concurrent.futures import ThreadPoolExecutor 

def download_contract_history(self, **kw): 
    ThreadPoolExecutor().map(lambda x: x.download_contract_history(**kw), self.instruments.values()) 
    print("All downloads complete.") 

を現時点では、すぐに「すべてのダウンロードが完了し、」印刷します。スレッドが実際に終了した後、ステートメントを印刷するにはどうすればよいですか? https://docs.python.org/dev/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor

答えて

0

理由:マップする

等価(FUNC、*イテラブル)FUNC以外は非同期に実行され、FUNCにいくつかの呼び出しを同時に行うことができます。

あなたが現在に滞在し気にしない場合:あなたは確かにprint文に続行されませんので

from multiprocessing.pool import ThreadPool as Pool 
Pool(processes=4).map(lambda x: x.download_contract_history(**kw),self.instruments.values()) 

プールマップ機能は、ブロッキング機能です。

あなたはおそらくそう定期的にマルチを使用するには、(私が思うに、私は間違って誰だなら、私を修正)このような何かのためのスレッド(GILをスレッドのGoogleのpython)を使用する必要はありません注:

from multiprocessing import Pool 
+0

ありがとうございました!なぜここでマルチプロセスが良いのか分かりますか? – cjm2671

+0

これは、将来のパッケージとは対照的に、既存の、よくテストされたコードであるためです。インポートしたパッケージから同期バージョンが見つかりませんでした(ブロックされるので、最後まで印刷されません)。なぜスレッドではなくプロセスであるかを尋ねるのであれば、それはPythonの仕組みに関する大きな話題です。私はgoogle "python gil threading"と言いました。 – kabanus

+1

各スレッドがIOを待っている時間のほとんどを費やしている場合、スレッドはそれほど悪くない。マッピングしている関数がURLからデータをダウンロードする場合マッピングしている関数が主に計算量、つまりCPUのビジーな作業である場合、スレッドは作業が並列化されないため、問題はありません。マルチプロセッシングでは、各マッピングされた関数は並行して作業できますが、シリアル化のオーバーヘッドがあります(親プロセスとサブプロセス間ではargsと結果の値をpickle/unpickする必要があります)。 – Anentropic

0

他のことを同時に行うことができることは、一種のポイントです。完了するのを待つ場合は、返された結果を確認する必要があります。

The docsは非常に明確ではないが、彼らは言う: __next__()が呼び出されたconcurrent.futures.TimeoutError場合

返されるイテレータは上昇し、その結果は、タイムアウト秒

だから、後に使用できません。 mapは結果イテレータを返し、その結果は未来のものではないため、実際の結果であるようです。

from concurrent.futures import ThreadPoolExecutor 

def download_contract_history(self, **kw): 
    results = list(
     ThreadPoolExecutor().map(
      lambda x: x.download_contract_history(**kw), 
      self.instruments.values() 
     ) 
    ) 
    print("All downloads complete.") 
関連する問題