web-dev-qa-db-ja.com

Pythonプール/キューを備えた複数のサブプロセスは、終了するとすぐに出力を回復し、キュー内の次のジョブを起動します

私は現在、サブプロセスを起動し、stdoutの解析が完了するのを待たずに、外出先でstdoutを解析しています。

for sample in all_samples:
    my_tool_subprocess = subprocess.Popen('mytool {}'.format(sample),Shell=True, stdout=subprocess.PIPE)
    line = True
    while line:
        myline = my_tool_subprocess.stdout.readline()
        #here I parse stdout..

私のスクリプトでは、実際に入力サンプルの数に応じて、このアクションを複数回実行します。

ここでの主な問題は、すべてのサブプロセスが、実行中に1つのCPUを100%使用するプログラム/ツールであるということです。そしてそれはしばらくかかります..多分入力ごとに20-40分。

私が達成したいのは、同時に実行されるN maxサブプロセスジョブプロセスのプール、キュー(ここで正確な用語が何であるかはわかりません)を設定することです。そのため、パフォーマンスを最大化することができ、順番に進めることはできませんでした。

したがって、たとえば最大4つのジョブプールの実行フローは次のようになります。

  • 4つのサブプロセスを起動します。
  • ジョブの1つが終了したら、stdoutを解析して、次に起動します。
  • キュー内のすべてのジョブが終了するまでこれを実行します。

これを達成できれば、どのサンプルサブプロセスが終了したかを特定する方法が本当にわかりません。現時点では、各サブプロセスが順番に実行され、サブプロセスがstdoutを出力しているときに、stdoutを解析するため、それらを識別する必要はありません。

各サブプロセスの出力を識別し、それに対応する入力/サンプルに割り当てる必要があるため、これは非常に重要です。

13
gmarco

ThreadPoolは問題に適している可能性があります。ワーカースレッドの数を設定してジョブを追加すると、スレッドはすべてのタスクを処理します。

from multiprocessing.pool import ThreadPool
import subprocess


def work(sample):
    my_tool_subprocess = subprocess.Popen('mytool {}'.format(sample),Shell=True, stdout=subprocess.PIPE)
    line = True
    while line:
        myline = my_tool_subprocess.stdout.readline()
        #here I parse stdout..


num = None  # set to the number of workers you want (it defaults to the cpu count of your machine)
tp = ThreadPool(num)
for sample in all_samples:
    tp.apply_async(work, (sample,))

tp.close()
tp.join()
19
GP89

私はあなたの質問を理解しましたが、あなたの問題は、終了後の最初のプロセスの結果が2番目のプロセスに提供され、次に3番目のプロセスに提供されるということです。これを実現するには、スレッドモジュールをインポートしてクラスThreadを使用する必要があります。

proc = threading.Thread(target=func, args=(func arguments) # Thread class
proc.start()                                   # starting the thread
proc.join()                                    # this ensures that the next thread does no 

前のものが終了するまで開始します.....

0
hayder alshawk

この場合、proc.join()なしで上記と同じコードを記述する必要があります。この場合、メインスレッド(main)が他の4つのスレッドを開始します。この場合、マルチスレッドはマルチコアプロセッサのメリットを享受するには、単一のプロセス(つまり、マルチコアプロセッサのメリットはありません)で、次のようなマルチプロセッシングモジュールを使用する必要があります。

proc = multiprocessing.Process(target=func, args=(funarguments))      
proc.start()

このように、それぞれが別々のプロセスになり、別々のプロセスが互いに完全に独立して実行できます

0
hayder alshawk