1

最初の Popens が解決される前に、Popen() であまりにも多くのプロセスを開始すると、どのくらいの危険性がありますか?

PDFで満たされたディレクトリで処理を行っています。各ファイルを反復処理し、外部呼び出しを使用して 2 つのことを行います。

まず、Xpdf ベースの pdftohtml ツールから HTML 表現を取得します (pdfminer は遅すぎます)。これにより、最初のページのみが出力されます。

html = check_output(['pdftohtml.exe','-f','1','-l','1','-stdout','-noframes',pdf])

次に、条件が満たされている場合 (それが適切なドキュメントであることを確認した場合)、それに対して tabula-extractor を呼び出してテーブルを抽出します。これは、ドキュメントのチェックに比べて低速/長時間実行されるプロセスであり、おそらく 1/20 ファイルでのみ発生します。

もしそうするだけならcall(['jruby', 'C:\\jruby-1.7.4\\bin\\tabula', .....])、抽出が完了するのを待つのに長い時間を費やし、より多くのファイルをチェックすることができます (私は 4 コアと 16 GB の RAM を持っていますが、Tabula はマルチスレッドではないようです)。

代わりに、ブロックを回避するために Popen() を使用しています。

Popen(['jruby', 'C:\\jruby-1.7.4\\bin\\tabula', '-o', csv, '-f', 'CSV', '-a', "'",topBorder, ',', leftBorder, ',', bottomBorder, ',', rightBorder, "'", '-p', '1', pdf]) 
#where CSV is the name of the output file and pdf is the name of the input

戻り値は気にしません (tabula は csv ファイルを作成しているので、作成が成功したかどうかは事後にいつでも確認できます)。このようにすることで、バックグラウンドでファイルをチェックし続け、必要に応じてより多くのタブラ プロセスを開始できます (これも 20 分の 1 程度です)。

これは機能しますが、バックログが発生し、一度に大量のタブラ プロセスを実行することになります。だから私の質問は:これは悪いですか?それ以外の理由でコンピューターの速度が低下しますが、クラッシュせず、可能な限り高速に動作している限り、私はあまり気にしません (4 つのコアすべてが常に 100% で動作しますが、メモリ使用量はそうではありません)。 5.5GB を超えると、CPU バウンドのように見えます)。

それが悪い場合、それを改善する正しい方法は何ですか? タブラ プロセスをキューに入れ、コアごとに常に 1 ~ 2 個のプロセスが実行されるようにする便利な方法はありますが、一度に 30 個のファイルを処理しようとはしていません。

4

1 に答える 1

4

タブラ プロセスをキューに入れ、コアごとに常に 1 ~ 2 個のプロセスが実行されるようにする便利な方法はありますが、一度に 30 個のファイルを処理しようとはしていません。

はい、multiprocessingモジュールはまさにそれを行います。

import multiprocessing
import subprocess

def process_pdf(path):
    subprocess.call(['jruby', 'C:\\jruby-1.7.4\\bin\\tabula', path, ...])

pool = multiprocessing.Pool(3)      # 3 processes
results = []
for path in search_for_files():
    results.append(pool.apply_async(process_pdf, [path]))
for result in results:
    result.wait()
于 2013-09-20T21:46:52.557 に答える