功能超时(Windows)?
我正在尝试为特定功能实现超时。我检查了SE中的许多问题,找不到适合我问题的解决方案,因为:
- 我在Windows中运行python
- 超时是在我无法控制的python函数上应用的,即它是在已经设计好的模块中定义的。
- python函数不是子进程
我已经MyModule
为特定任务开发了一个已经设计好的定制模块(例如),并且其中定义了功能。其中一个功能(例如MyFunc
)由于外部因素而倾向于永久运行,而我只是不希望python脚本挂起。
我打算添加一个超时功能,如下面的伪代码所示:
import MyModule
set_timeout(T)
MyResult=MyModule.MyFunc()
#Come to this part of script after execution of MyFunc() or after T seconds (the latter on priority)
if Timeout occurred:
print 'MyFunc did not execute completely'
else:
print 'MyFunc completed'
但是我不确定哪个模块可以在python上实现。请注意,我是新手,并且我编写的所有脚本都直接基于SE Answers或Python文档。
-
我认为解决此问题的一种好方法是创建一个装饰器并使用该
Thread.join(timeout=seconds)
方法。请记住,没有杀死线程的好方法,因此只要您的程序正在运行,它就会或多或少在后台继续运行。首先,创建一个这样的装饰器:
from threading import Thread import functools def timeout(timeout): def deco(func): @functools.wraps(func) def wrapper(*args, **kwargs): res = [Exception('function [%s] timeout [%s seconds] exceeded!' % (func.__name__, timeout))] def newFunc(): try: res[0] = func(*args, **kwargs) except Exception as e: res[0] = e t = Thread(target=newFunc) t.daemon = True try: t.start() t.join(timeout) except Exception as je: print ('error starting thread') raise je ret = res[0] if isinstance(ret, BaseException): raise ret return ret return wrapper return deco
然后,执行以下操作:
func = timeout(timeout=16)(MyModule.MyFunc) try: func() except: pass #handle errors here
您可以在需要的任何地方使用此装饰器,例如:
@timeout(60) def f(): ...