我使用的是jython 2.7 jsr223脚本引擎。我希望在终止jython执行时进行清理。
终止:中断运行jython脚本引擎的线程。
清理:注册signal handlers: signal.signal(signal.SIGTERM,cleanup)
在jython代码中,我看到,作为一个例子,sleep会对抛出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,“中断睡眠”)。
理论上可以捕获KeyboardInterrupt异常并且可以执行信号处理程序。然而,所有命令都不会始终抛出KeyboardInterrupt。 jython中的subprocess.check_call命令的实现方式是它不会抛出KeyboardInterrupt异常,也不会在jython执行中断时触发任何SIGINT或SIGTERM。 因此,kill行为可能会在当前正在执行的python-java等效项(jython命令)的实现上发生变化。
有类似问题的人说改变jython控制台会有助于触发SIGINT。 :How do you intercept a keyboard interrupt (CTRL-C) in Jython?
所以我设置了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信号。但执行关闭钩子:What happens when the JVM is terminated?
调试关闭挂钩并未显示它们在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信号处理程序???
非常感谢你的帮助!