0

command_1 から command_3 までのファイルのチャンクを処理するように定義された 3 つの関数 (2 つのループ) があり、終了したら、同じワークフローを使用して別のチャンクを処理します。

ここに示す擬似コード

実際のコードはより長く、機能しています:

def run(cmd):
  try:
    subprocess.Popen(command,shell='True')
  except:
    exit()

def run_chunk(chunk,command,flag=False)
  for file in chunk
    cmd = eval(command+'("' + bam + ')"') 
    run(cmd)
def main():
  chunks = [[chunk1],[chunk2]...]
  for chunk in chunks:
    run_chunk(chunk, command_1, True)
    os.waitpid(-1,0)
    run_chunk(chunk, command_2, True)
    os.waitpid(-1,0)
    run_chunk(chunk, command_3, True)
    os.waitpid(-1,0)

注: eval は文字列を返します。これは、「実行」機能のコマンドです。

私の問題は、command_1 を実行すると、os.waitpid() が機能しているように見えることです。command_1 が終了すると、プログラムは command_2 に移動します。command_2 は command_3 に移動する前に待機しているように見えますが、メイン関数の外側のループは command_1 をすぐに実行します (これは望ましくありません)。

コードのバグを見つけられる人はいますか? どうもありがとう!

4

2 に答える 2

1

を呼び出すたびに、run_chunk多くの子サブプロセスが生成される場合があります。子サブプロセスが終了os.waitpid(-1, 0)するのを待ちます。に多くのファイルがある場合、すべての子サブプロセスが完了する前chunkos.waitpid(-1, 0)が戻ります。したがって、後続の への呼び出しが早すぎる可能性があります。run_chunk

各呼び出しをrun順番に実行する場合は、 in への呼び出しを追加しproc.communicate()ますrun

def run(cmd):
    try:
        proc = subprocess.Popen(cmd, shell=True)
        proc.communicate()
    except:
        exit()

runによって生成されたすべての呼び出しを同時に発生させたい場合run_chunk、おそらく最も簡単な方法は、マルチプロセッシング ThreadPoolを使用することです。

import multiprocessing.pool as mpool

def run(cmd):
    try:
        proc = subprocess.Popen(cmd, shell=True)
        proc.communicate()
    except:
        exit()

def run_chunk(chunk, command, flag=False):
    for file in chunk:
        cmd = eval(command + '("' + bam + ')"')
        pool.apply_async(run, args=(cmd,))
    pool.join()  # wait until all the calls to run have completed.

def main():
    chunks = [[chunk1], [chunk2]...]
    for chunk in chunks:
        run_chunk(chunk, command_1, True)
        run_chunk(chunk, command_2, True)
        run_chunk(chunk, command_3, True)

if __name__ == '__main__':
    pool = mpool.ThreadPool() 

ここでは、通常のマルチプロセッシング プールの代わりに ThreadPool を使用することにしましたsubprocess.Popen。これは、プール内の各ワーカーが を呼び出すだけで、新しいサブプロセスが生成されるためです。プール内のワーカーは、そのサブプロセスが終了するのを待つだけです。そのため、ワーカーを独自のサブプロセスで実行するのは無駄に思えました。軽量なスレッドで十分だと思います。

をインスタンス化するときに数を指定しない場合mpool.ThreadPool、CPU コアと同じ数のワーカー スレッドを含むプールが取得されます。各ワーカースレッドは当然コアを必要とするサブプロセスを生成するため、これは私にとって最適に思えます。したがって、コアよりも多くのワーカー スレッド (したがって、より多くのサブプロセス) を持つことには意味があります。

于 2013-07-01T17:35:50.390 に答える