【发布时间】:2021-04-10 23:05:19
【问题描述】:
我需要实现一个功能来监控正在运行的作业的状态,直到它完成。像这样的:
def monitor_job(job_id):
ended = False
while not ended:
ended = check_if_ended(job_id)
time.sleep(5)
print('ended')
现在我想允许用户使用 Ctrl-C 中断循环,在这种情况下,我想优雅地调用 stop_job() 函数来停止工作。但是这个函数是异步的,它只是提交一个停止作业的请求,这可能需要一些时间才能完成。因此,在这个电话之后,我想继续 while 循环并等待工作结束。这是一个尝试:
def monitor_job(job_id):
keybreaks = False
ended = False
while not ended:
# (...)
try:
ended = check_if_ended(job_id)
time.sleep(5)
except KeyboardInterrupt:
# break after a second keybreak
if keybreaks:
raise
keybreaks = True
stop_job(job_id)
print('ended')
我在这个解决方案中不喜欢的是,如果偶然在 try 之外触发了 Ctrl-C(例如在 (...)),那么将不会捕获异常,并且作业不会优雅地停止。
有没有好的方法来正确处理这个问题,避免这种时间问题?
我想到了一些解决方案,例如:在 except 块内复制 while 循环,这并不优雅;或者将try 放在while 循环之外,然后在except 中回调monitor_job(),但是在函数调用期间可能会发生Ctrl-C。
【问题讨论】:
-
如果您没有在
try((...)所在的位置)之外放置任何代码,那么它应该始终被捕获。因此,只需将while和try语句之间的所有内容移动到try块中。 -
你的意思是它不太可能发生或不可能发生?我想让它原则上不可能
-
这“只是”非常不可能,但几乎不可能。因为与其他所有内容相比,您的睡眠时间是如此之长,所以
sigint不太可能在 try 块之外命中。对于“原则上不可能”,请参阅下面的答案。祝你有美好的一天!
标签: python loops exception atomic