【发布时间】:2016-03-31 03:30:53
【问题描述】:
您好,我在 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 循环链中的另一个元素。
在一些cmets和答案之后添加以下部分:
我尝试使用 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()
...
【问题讨论】:
-
你说的“这个函数运行的程序”是什么意思?它是由
subprocess模块启动的外部进程吗?有后代进程吗?如果您发送 SIGTERM 信号,进程是否会退出?你的 Python 版本是什么?如果没有后代并且进程在SIGTERM上退出,则将timeout参数传递给process.wait()并在TimeoutError 上调用process.terminate()就足够了。 -
@J.F.Sebastian 此代码运行一个函数,该函数运行一个 fortran 代码,我想限制从 cpu 保存的运行时间。所有这个功能所做的就是将 fortran 代码留在后台并跳到 for 循环中的另一个元素,该循环在 100 个周期后堆积在 cpu 中,可以说,所以我想在跳到另一个元素之前终止会话。 Python 2.7 版。
-
@jackaraz 再次,“运行 fortran 代码”是否意味着您使用
subprocess模块运行外部进程? (例如,numpy库运行大量 fortran 代码无需启动新进程)。要限制并发进程的数量,请参阅this answer。 -
@J.F.Sebastian 是的,我在另一个函数中使用
subprocess.check_output('./../bin/SPhenoUMSSM ../UMSSM/LH_out_'+mod+' > SPheno_log_'+mod, shell=True)来运行 fortran 代码
标签: python popen terminate sys termination