函数调用超时

新手上路,请多包涵

我在 Python 中调用一个函数,我知道它可能会停止并迫使我重新启动脚本。

我如何调用该函数或将其包装在什么中,以便如果它花费超过 5 秒的时间,脚本将取消它并执行其他操作?

原文由 Teifion 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 344
2 个回答

如果您在 UNIX 上运行,则可以使用 信号 包:

 In [1]: import signal

# Register an handler for the timeout
In [2]: def handler(signum, frame):
   ...:     print("Forever is over!")
   ...:     raise Exception("end of time")
   ...:

# This function *may* run for an indetermined time...
In [3]: def loop_forever():
   ...:     import time
   ...:     while 1:
   ...:         print("sec")
   ...:         time.sleep(1)
   ...:
   ...:

# Register the signal function handler
In [4]: signal.signal(signal.SIGALRM, handler)
Out[4]: 0

# Define a timeout for your function
In [5]: signal.alarm(10)
Out[5]: 0

In [6]: try:
   ...:     loop_forever()
   ...: except Exception, exc:
   ...:     print(exc)
   ....:
sec
sec
sec
sec
sec
sec
sec
sec
Forever is over!
end of time

# Cancel the timer if the function returned before timeout
# (ok, mine won't but yours maybe will :)
In [7]: signal.alarm(0)
Out[7]: 0

调用 signal.alarm(10) 10 秒后,处理程序被调用。这会引发一个异常,您可以从常规 Python 代码中截取该异常。

这个模块不能很好地使用线程(但是,谁呢?)

请注意, 由于我们在超时发生时引发异常,它最终可能会在函数内部被捕获并忽略,例如一个这样的函数:

 def loop_forever():
    while 1:
        print('sec')
        try:
            time.sleep(10)
        except:
            continue

原文由 piro 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以使用 multiprocessing.Process 来做到这一点。

代码

import multiprocessing
import time

# bar
def bar():
    for i in range(100):
        print "Tick"
        time.sleep(1)

if __name__ == '__main__':
    # Start bar as a process
    p = multiprocessing.Process(target=bar)
    p.start()

    # Wait for 10 seconds or until process finishes
    p.join(10)

    # If thread is still active
    if p.is_alive():
        print "running... let's kill it..."

        # Terminate - may not work if process is stuck for good
        p.terminate()
        # OR Kill - will work for sure, no chance for process to finish nicely however
        # p.kill()

        p.join()

原文由 ATOzTOA 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏