2

我正在使用 jython 2.7 jsr223 脚本引擎。而且我喜欢在 jython 执行终止时进行清理。

终止:中断运行 jython 脚本引擎的线程。

清理:注册信号处理程序:signal.signal(signal.SIGTERM, cleanup)

在 jython 代码中,我看到,作为一个示例,睡眠会引发 KeyboardInterruot 异常。下面的代码:

public static void sleep(double secs) {
if (secs == 0) {
    // Conform to undocumented, or at least very underdocumented, but quite
    // reasonable behavior in CPython. See Alex Martelli's answer,
    // https://stackoverflow.com/a/790246/423006
    java.lang.Thread.yield();
} else {
    try {
        java.lang.Thread.sleep((long)(secs * 1000));
    }
    catch (java.lang.InterruptedException e) {
        throw new PyException(Py.KeyboardInterrupt, "interrupted sleep");
        }
    }
}

上面的代码引发了一个新异常:PyException(Py.KeyboardInterrupt, "interrupted sleep")。

理论上可以捕获 KeyboardInterrupt 异常并执行信号处理程序。然而,KeyboardInterrupt 并非始终与所有命令一起抛出。jython 中的 subprocess.check_call 命令以不引发 KeyboardInterrupt 异常的方式实现,也不会在 jython 执行中断时触发任何 SIGINT 或 SIGTERM。因此,kill 行为可能会在当前执行的 python-java 等效项(jython 命令)的实现上发生变化。

有类似问题的人说,更改 jython 控制台将有助于触发 SIGINT。:如何在 Jython 中拦截键盘中断 (CTRL-C)?

所以我设置了python.console=org.python.core.PlainConsole。Jython 代码说:或者,您可以在此处设置 python.console,

但请注意,这也会影响嵌入 PythonInterpreter 或使用 Jython 作为 JSR-223 脚本引擎的应用程序中的控制台。

所以应该会通过jsr223影响脚本引擎的执行。但是即使将 python.console=org.python.core.PlainConsole 作为 JVM 中设置的属性,也不会触发 SIGINT 脚本处理程序。

因此,当 jython 执行运行子进程并被中断时,似乎没有办法进行清理。

尽管如此,我发现当我中断运行节点的 jvm 时,会执行 jython 执行中的信号处理程序。该线程表示 JVM 终止不转发 SIGTERM 或 SIGINT 信号。但是执行关闭钩子:当JVM终止时会发生什么?

调试关闭挂钩并没有显示它们在 jvm 终止时的执行情况。

那么 SIGINT 和 SIGTERM 处理程序如何以及为什么以这种方式执行?

下面是使用 jython 测试信号处理程序和 KeyboardInterrupt 异常的代码:

import subprocess
import sys
import signal
import time

print 'Start'

def cleanup(signum, frame):
    outputFile = open('output.log','w')
    print "Starting cleanup"
    outputFile.write("Start cleanup")
    time.sleep(5)
    outputFile.write("Finished cleanup")
    outputFile.close()
    print "Done"
    sys.exit(0)

signal.signal(signal.SIGTERM, cleanup)
signal.signal(signal.SIGINT, cleanup)

try: outputFile = open('output.log','w')
    outputFile.write("Start sleeping bash subprocess:")
    outputFile.close()
    subprocess.check_call("sleep 10h", shell=True)
except KeyboardInterrupt as interrupt: outputFile = open('output.log','w')
    outputFile.write("Keyboard INterrupt caught")
    outputFile.close()

当 jsr223 jython 脚本引擎线程中断(执行终止)时,如何执行 python/jython SIGTERM 和 SIGINT 信号处理程序???

非常感谢你的帮助!

4

0 回答 0