13

スクリプトAPIの一部としてPythonを使用する商用アプリケーションを使用しています。提供される関数の1つは、と呼ばれるものApp.run()です。この関数が呼び出されると、残りの実行を行う新しいJavaプロセスが開始されます。.pyc(残念ながら、提供されているPythonモジュールはファイルであり、Python関数の多くはSWIGで生成されているため、内部で何が行われているのかはわかりません)。

私が抱えている問題はApp.run()、保証されたクリーンアップコード(データベースを閉じるなど)を実行する必要がある、より大きなPythonアプリケーションに呼び出しを構築していることです。残念ながら、サブプロセスがCtrl+Cで中断された場合、サブプロセスは中止され、メインのPythonプログラムに制御を戻さずにコマンドラインに戻ります。したがって、クリーンアップコードは実行されません。

これまでに試しました:

  1. atexitに関数を登録しています...機能しません
  2. クラス__del__デストラクタにクリーンアップを入れても...機能しません。(App.run()クラス内)
  3. CtrlメインのPythonアプリで+のシグナルハンドラーを作成してCいます...機能しません
  4. スレッドを挿入すると... +App.run()の後にメモリ障害が発生しますCtrlC
  5. (マルチプロセッシングApp.run()からの)プロセスを入れる...機能しない

何が起こっているのか考えてみませんか?

4

3 に答える 3

4

これは単なる概要ですが、このようなものですか?

import os

cpid = os.fork()
if not cpid:
    # change stdio handles etc
    os.setsid() # Probably not needed
    App.run()
    os._exit(0)

os.waitpid(cpid)
# clean up here

(os.forkは* nixのみです)

subprocess同じアイデアをOSに依存しない方法で実装できます。アイデアは子プロセスで実行App.run()され、子プロセスが終了するのを待っています。子プロセスがどのように死んだかに関係なく。posixでは、SIGCHLD(子プロセスの死)をトラップすることもできます。私はWindowsの第一人者ではないので、該当してsubprocess機能しない場合は、他の誰かがここでチャイムを鳴らす必要があります。

呼び出された後App.run()、プロセスツリーがどのように見えるのか興味があります。を実行execしてPythonプロセススペースを引き継ぐ可能性があります。それが起こった場合、子プロセスを作成することが、それをトラップすることを考える唯一の方法です。

于 2012-10-17T18:33:45.643 に答える
2

try: App.run() finally: cleanup()動作しない場合; サブプロセスで実行してみることができます。

import sys
from subprocess import call

rc = call([sys.executable, 'path/to/run_app.py'])
cleanup()

または、文字列にコードがある場合は、次の-cオプションを使用できます。

rc = call([sys.executable, '-c', '''import sys
print(sys.argv)
'''])

ここでプロセスグループの作成がどのように役立つかはわかりませんが、preexec_fn=os.setsid引数(注:no )を追加することで、サブプロセスを使用して@tMCの提案を実装でき ます。()または、shell=True引数を試して別のシェルで実行することもできます。

マルチプロセッシングをもう一度試してみてください。

import multiprocessing as mp

if __name__=="__main__":
   p = mp.Process(target=App.run)
   p.start()
   p.join()
   cleanup()
于 2012-10-17T20:52:10.650 に答える
1

App.Run()をTry / Catchでラップできますか?

何かのようなもの:

try:
    App.Run()
except (KeyboardInterrupt, SystemExit):
    print "User requested an exit..."
cleanup()
于 2012-10-17T18:34:53.707 に答える