函数调用超时

37 浏览
0 Comments

函数调用超时

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

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

admin 更改状态以发布 2023年5月22日
0
0 Comments

\n\n您可以使用 multiprocessing.Process 来实现这一点。\n\n代码\n\n

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()

0
0 Comments

如果您正在运行UNIX,可以使用信号(signal)软件包:

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

0