13

我正在使用一个商业应用程序,它使用 Python 作为其脚本 API 的一部分。提供的功能之一是称为App.run(). 当这个函数被调用时,它会启动一个新的 Java 进程来完成其余的执行。(不幸的是,我真的不知道它在幕后做了什么,因为提供的 Python 模块是.pyc文件,并且许多 Python 函数是 SWIG 生成的)。

我遇到的麻烦是我正在将App.run()调用构建到一个更大的 Python 应用程序中,该应用程序需要执行一些有保证的清理代码(关闭数据库等)。不幸的是,如果子进程被Ctrl+中断C,它会中止并返回命令行,而不会将控制权返回给 Python 主程序。因此,我的清理代码永远不会执行。

到目前为止,我已经尝试过:

  1. 用 atexit... 注册函数不起作用
  2. 将清理放在类__del__析构函数中......不起作用。(App.run()在课堂内)
  3. Ctrl在主 Python 应用程序中为+创建信号处理C程序...不起作用
  4. 放入App.run()线程...导致Ctrl+后出现内存错误C
  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可以以与操作系统无关的方式实现相同的想法。思路是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 )使用 subprocess 来实现@tMC 的建议, ()尽管我看不出在这里创建流程组可能有什么帮助。或者你可以试试shell=True使用参数在单独的 shell 中运行它。

您可能会再次尝试多处理:

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 回答