我循环遍历列表并对列表的每个成员执行某些操作。
如果一个成员花了太多时间(在这种情况下是1秒),我打算通过它。但是try
语句中的块始终处理并且永不超时。我不明白为什么。
from eventlet import *
for rule in data:
#Timeout block
t=Timeout(1)
try:
f = expr2bdd(expr(rule))
solutions = satisfy_all(f, count=True)
each_rule["solution"]=solutions
except:
pass
finally:
t.cancel()
答案 0 :(得分:1)
Eventlet是一个并发的网络库......
不清楚expr2bdd
和satisfy_all
函数的作用,但很可能它们只进行一些CPU计算而没有磁盘/网络IO。在这种情况下,没有任何一点可以让Eventlet有机会运行并触发超时异常。
如果您可以控制expr2bdd
和satisfy_all
个函数并且存在任何类型的循环,请在每次迭代时放置eventlet.sleep(0)
。这是“对其他协同程序进行控制权”的Eventlet习惯用法,即超时将被触发的地方。
如果您无法控制所述功能,那么第二个最佳选择是在一个可以强行杀死的单独进程中运行它们。在POSIX兼容的操作系统(例如Linux,* BSD,OSX)上,您可以使用os.fork
在单独的进程中运行一段代码。为获得最大的便携性,请使用subprocess.Popen([sys.executable,...])
或multiprocessing.Process
。后者提供更高级别的API,主要围绕更容易的数据交换(序列化)而牺牲性能开销,这在您的情况下可以忽略不计。在任何情况下,基本模式是这样的:(在线程或事件小程序中,你启动第二个进程,然后.communicate()/join()
就可以了。使用eventlet.Timeout
或Thread.join()
超时。如果超时发生,使用p.terminate()
或p.kill()
停止当前计算。