2

私は次のコードを持っています (Pool クラスに関するいくつかの仮定をテストしているだけです):

#!/usr/bin/env python
from time import sleep
from multiprocessing import Pool

def run_process(args):
    print "Sleeping %d seconds" % (args * 2)
    sleep(args * 2)
    print "Slept %d seconds" % (args * 2)

def main():
    test = [1,2,3,1,2,3,1,2,3]
    pool = Pool()
    pool.map_async(run_process, test).get()

if __name__ == '__main__':
    main()

最終的には、コマンド (つまり、別のプロセス) を生成するために、test各呼び出しに渡される引数のリストになります。run_process

Ctrl+を押すCと、残念ながら、直接の子プロセスを破棄することさえありません(ドキュメントからは、単に子Poolプロセスを作成するように聞こえます)。端末 (Ubuntu 10.04、Python 2.6.5、これが重要な場合) で何が起こるかと^Cいうと、押すたびにエコーが表示されますが、すべての子が「ジョブ」を終了する必要があるときに親が時間内に死ぬこともありません (つまり、眠っている)、親プロセスを強制終了せずに端末を再利用することもできませんでした。

直接の子 (および後で生成されたコマンド) を破棄するようにスクリプトを調整するにはどうすればよいですか? 私がしようとしているのは、シグナルハンドラーから使用することだと思いますか? multiprocessing.Pool.close()!multiprocessing.Pool.terminate()

注意: ここでは意図的にスレッドではなくプロセスを使用しているので、解決策でそれを考慮していただければ幸いです。


この質問への回答を読んだ後に試したことが1つありますが、同じ問題に悩まされています。

#!/usr/bin/env python
from signal import signal
from time import sleep
from multiprocessing import Pool

def init_worker():
    import signal
    signal(signal.SIGINT, signal.SIG_IGN)

def run_process(args):
    print "Sleeping %d seconds" % (args * 2)
    sleep(args * 2)
    print "Slept %d seconds" % (args * 2)

def main():
    test = [1,2,3,1,2,3,1,2,3]
    try:
        pool = Pool()
        pool.map_async(run_process, test).get()
    except KeyboardInterrupt:
        pool.terminate()
        pool.wait()

if __name__ == '__main__':
    main()

非常に大きなタイムアウト (ジョブは数週間実行される可能性があるため、タイムアウトはそれをカバーするのに十分な大きさでなければなりません) を追加すると、+Pool.get()を使用できるように見えますが、出力はやや混乱します。CtrlC

Traceback (most recent call last):
  File "./test.py", line 26, in <module>
    main()
  File "./test.py", line 23, in main
    pool.wait()
AttributeError: 'Pool' object has no attribute 'wait'

try/を取り除いた後except、トレースバックは「より自然」に見えます。したがって、トリックは、行を元のスクリプトから、目的に合わせて十分な大きさのタイムアウトのpool.map_async(run_process, test).get()ようなものpool.map_async(run_process, test).get(999999)に変更することです。999999

4

0 に答える 0