2015-12-29 10 views
5

私はいくつかのサブプロセス(マルチプロセッシングを使用しています)を持っていますが、それらが停止すると、最終作業が必要になります。しかし、うまくいかなかった次のようなもの...Pythonのマルチプロセッシングサブプロセスで "atexit"関数を登録するには?

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() 

どうすればいいですか?

+0

あなたが達成しようとしているものに似ているhttp://stackoverflow.com/questions/1231599/python-multiprocessing-exit-elegantly-howを確認してください。 –

答えて

1

マルチプロセスで開始されたプロセスは正常に終了せず、atexit関数は呼び出されません。あなたが本当にatexitを使用する場合(欠点については以下を参照)、

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

をか:あなたは、たとえば、のtry/finallyブロックを経由して、手動でクリーンアップのものを実行する必要が

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

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

技術的には、they quit via os._exit()なので、クリーンアップジョブ(atexit関数、__del__()、weakrefファイナライザを含む)をスキップします。

この決定の背後にあるのは、間違った時間に不正なプロセスでクリーンアップが実行される危険性があるからです。 atexit(または他のメカニズム)を使用するコードの大部分は、コードが一度だけ実行されることを期待しています。たとえば、メインインタープリタが終了したときのみです(たとえば、atexitを使用して一時ディレクトリを削除できます)。サブプロセスが終了するたびにatexit関数を実行すると、この期待を破り、悪いことが起こる可能性があります。

だから、あなたはatexit._run_exitfuncs()経由atexitの機能を実行することができていても、機能が文書化されていないで、両方のために、そうすることを回避し、あなたがないかもしれませんので、atexit(他のサードパーティのライブラリのユーザーだけがそれを使用することができ、あなたが導入することができますそのコードのバグ)。

+0

これは不合理な決定でした。 atexit関数は "main"から呼び出されることは期待しません。彼らは登録された過程で呼ばれることを期待しています。だから、atexitは呼び出すことができるかどうかを知るために登録のPIDを格納するだけでよい。 atexitを使用するモジュールは、マルチプロセッシングジョブの中では役に立たないようになりました...代わりにPopenを使用し、自分の状態をpickleするように強制しました。私は実際に適切なクリーンアップを入れるためにマルチプロセッシングをフォークしました。 –

関連する問題