您好我在我的python代码中嵌入了一个时间限制,该代码运行带有函数的fortran代码。但是我意识到将时间约束放在另一个函数上的函数并没有终止代码,只是将它留在后台并改为跳过它。我想要做的是在超过约束时间时终止代码。以下是我用来约束here时间的代码。
def timeout(func, args=(), kwargs={}, timeout_duration=15, default=1):
import signal
class TimeoutError(Exception):
pass
def handler(signum, frame):
raise TimeoutError()
# set the timeout handler
signal.signal(signal.SIGALRM, handler)
signal.alarm(timeout_duration)
try:
result = func(*args, **kwargs)
except TimeoutError as exc:
result = default
finally:
signal.alarm(0)
return result
我查了popen.terminate()
,sys.exit()
和atexit.register()
,但无法弄清楚它是如何处理这段代码的,我试图在下面添加一部分代码在评论中显示。
...
result = func(*args, **kwargs)
except TimeoutError as exc:
result = default
#add the terminator
finally:
...
注意:函数在for循环链中,所以我不想杀死整个python会话但只想杀死这个函数运行的程序,这是一个fortran代码并跳转到for循环链中的另一个元素。 / p>
以下部分经过一些评论和回答后添加:
我尝试使用popen.terminate()添加SIGTERM但是它终止了所有python会话,我只想终止当前运行的会话并跳转到for循环中的其他元素。我做的是如下:
...
signal.signal(signal.SIGTERM, handler)
signal.alarm(timeout_duration)
try:
result = func(*args, **kwargs)
except TimeoutError as exc:
result = default
popen.terminate()
...
答案 0 :(得分:1)
您不能指望信号处理程序通过调用堆栈传播Exception,并在不同的上下文中调用它。
popen.terminate()
会在posix系统上生成SIGTERM
,因此您应该拥有SIGTERM
而非SIGALRM
的信号处理程序。
您应该设置一些定期检查以暂停活动的变量,而不是在信号处理程序中引发异常。
或者,如果您没有SIGTERM
的信号处理程序,则默认处理程序可能会生成KeyboardInterrupt
例外。