12

いくつかのサブプロセス (マルチプロセッシングを使用) があり、それらが停止すると、それぞれが最終的な作業を行う必要があります。次のようなものですが、うまくいきませんでした...

import multiprocessing
import atexit

def final():
    print "final work"

def worker():
    print 'Doing some work'
    atexit.register(final)

if __name__ == '__main__':
    p = multiprocessing.Process(target=worker)
    p.start()
    p.join()

では、どうすればこれを行うことができますか?

4

2 に答える 2

9

マルチプロセッシングによって開始されたプロセスは正常に終了せず、atexit関数は呼び出されません。次のように、try/finally ブロックを介して手動でクリーンアップを実行する必要があります。

def worker():
    try:
        print('Doing some work')
    finally:
        final()

または、本当に使用したい場合atexit(欠点については以下を参照):

def worker():
    try:
        print('Doing some work')
    finally:
        atexit._run_exitfuncs()

サブプロセスが正常に終了しないのはなぜですか?

技術的には、を介して終了するos._exit()ため、クリーンアップ ジョブ (atexit関数、__del__()weakref ファイナライザーを含む) をスキップします。

この決定の背後にある理由は、クリーンアップが間違ったタイミングで間違ったプロセスで実行されるリスクがあるためです。(または他のメカニズム)を使用するコードのほとんどはatexit、メイン インタープリターが終了するときにのみ、コードが 1 回だけ実行されることを想定しています (たとえば、atexit一時ディレクトリを削除するために使用する場合があります)。atexitサブプロセスが終了するたびに関数を実行すると、この期待が崩れ、悪いことが起こる可能性があります。

atexitそのため、を介して関数を実行することはできますがatexit._run_exitfuncs()、関数が文書化されていないことと、 の唯一のユーザーではない可能性があるためatexit(他のサードパーティ ライブラリがそれを使用している可能性があり、コードにバグを導入する可能性があるため)、そうすることは避けてください)。

于 2015-12-29T08:47:05.523 に答える
0

atexitマルチプロセス対応のこの代替品を使用できます。

プロセス自体によって登録された関数のみを呼び出し、親プロセスなどから継承された他の関数は呼び出しません。

https://github.com/kuralabs/multiexit

于 2018-04-07T05:35:34.630 に答える