IO

2017-08-22 20 views
0

は基本的に私は現在、次のことをやっている:IO

for bigLogFile in bigLogFileFolder: 
    with open(bigLogFile) as bigLog: 
     processBigLogfile(bigLog) 

私はネットワークドライブからこのログファイルをロードしておりますので、実行時間の大部分は、ファイルを待っていますロードする。しかし、processBigLogFileの実行時間も簡単ではありません。

私の基本的な考え方は、プロセスを非同期にして、現在のログが処理されている間にプログラムが次のログファイルをロードできるようにすることでした。 シンプルだが、私は非同期プログラミングで何の経験もなく、asyncioは私がやりたいことを達成するためのさまざまな方法を提供しているようだ(タスクや未来の使用は有望な候補者だったようだ)。

これを達成する最も簡単な方法を誰にでも教えてもらえますか? Asyncioは厳密には必要ではないですが、私は強く使用して希望ビルトインライブラリ

ログファイルが順番に処理しなければならないので、私は単にロードと処理ファイルをparallellizeことができないことに留意すべきである

答えて

1

同じことが、簡単なThreadPoolExecutorで実現することができ、複雑なasynchrounousコーディングのための必要はありません:

from concurrent.futures import ThreadPoolExecutor 

with ThreadPoolExecutor(max_workers=1) as tp: 
    for bigLogFile in bigLogFileFolder: 
     with open(bigLogFile) as bigLog: 
      data = bigLog.read() 
      tp.submit(process_data, data) 

ThreadPoolExecutorは、ボンネットの下にキューを使用しているため、処理の順序は限りmax_workers=1として保存されます。

また、すべての/ほとんどのファイルを保持するのに十分なメモリがある場合は正常に動作します。メモリにバインドされている場合、ThreadPoolExecutorがいくつかのタスクを完了するのを待たなければなりません。

+0

ニースのソリューション!以前はキューを使用してマルチスレッドを行ってきましたが、私がやりたいことを実装するためにプール・サイズを1にすることは考えていませんでした。 – user2983738

0

ファイルのオープンを並列化したいが、処理は順次であるように思える。それがいつでもあなたを救うかどうかは分かりません。

from concurrent.futures import ThreadPoolExecutor, as_completed 

bigLogFileFolder = [...] 

num = len(bigLogFileFolder) 

pool = ThreadPoolExecutor(num) 

futures = [pool.submit(open, bigLogFile) for bigLogFile in bigLogFileFolder] 

for x in as_completed(futures): 
    processBigLogFile(x.result()) 
+0

私は必ずしも並列化する必要はありません、私はちょうど現在のファイルが処理されている間、次のファイルをプリロードしたかったのです。これは理想的には処理時間を半分にします(ファイルの読み込みと処理に同じ時間がかかる場合)。あなたと奇妙な人の両方がThreadPoolExecutorを使用するので、それは行く方法のようです。 – user2983738

+0

さて、 'open'を出すのではなく、ファイルの内容を開いて読み込んで返す独自の関数を提出することができます。 (必要に応じてあらかじめ処理することもできます)。この開放と読書は並行して行われる。それで 'processBigLogFile()'関数はファイル内容全体を(文字列として)取って、その処理を実行する必要があります。これらの内容は順番に提示される。だから、不気味な点があるので、同時にすべてのコンテンツを保持する必要があります。 – quamrana