我正在使用 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 信号处理程序???
非常感谢你的帮助!