无法使用 python eventlet 库 (eventlet.timeout.Timeout) 超时
Not able to timeout using python eventlet library (eventlet.timeout.Timeout)
我正在遍历一个列表并对列表的每个成员执行一些操作。
如果一个成员花费太多时间(在这种情况下为 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()
Eventlet is a concurrent networking library...
不清楚 expr2bdd
和 satisfy_all
函数的作用,但很可能它们只进行一些 CPU 计算而没有 disk/network IO。在这种情况下,Eventlet 没有机会 运行 并触发超时异常。
如果您可以控制 expr2bdd
和 satisfy_all
函数并且存在任何类型的循环,请在每次迭代时放置 eventlet.sleep(0)
。这是 "yield control to other coroutines" 的 Eventlet 习语,这就是触发超时的地方。
如果您无法控制上述功能,第二个最佳选择是 运行 在一个单独的进程中将它们强制终止。在 POSIX compatible OS (e.g. Linux, *BSD, OSX) 上,可以用 os.fork
到 运行 一块在单独的过程中的代码。为了获得最大的可移植性,请使用 subprocess.Popen([sys.executable,...])
或 multiprocessing.Process
。后者提供了更高级别 API,主要围绕以性能开销为代价的更容易的数据交换(序列化),这在您的情况下可以忽略不计。在任何情况下,基本模式是这样的:(在线程或 eventlet 协程中,您启动第二个进程,然后在其上 .communicate()/join()
。使用 eventlet.Timeout
或 Thread.join()
超时。如果超时触发, 使用 p.terminate()
或 p.kill()
停止当前计算。
我正在遍历一个列表并对列表的每个成员执行一些操作。
如果一个成员花费太多时间(在这种情况下为 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()
Eventlet is a concurrent networking library...
不清楚 expr2bdd
和 satisfy_all
函数的作用,但很可能它们只进行一些 CPU 计算而没有 disk/network IO。在这种情况下,Eventlet 没有机会 运行 并触发超时异常。
如果您可以控制 expr2bdd
和 satisfy_all
函数并且存在任何类型的循环,请在每次迭代时放置 eventlet.sleep(0)
。这是 "yield control to other coroutines" 的 Eventlet 习语,这就是触发超时的地方。
如果您无法控制上述功能,第二个最佳选择是 运行 在一个单独的进程中将它们强制终止。在 POSIX compatible OS (e.g. Linux, *BSD, OSX) 上,可以用 os.fork
到 运行 一块在单独的过程中的代码。为了获得最大的可移植性,请使用 subprocess.Popen([sys.executable,...])
或 multiprocessing.Process
。后者提供了更高级别 API,主要围绕以性能开销为代价的更容易的数据交换(序列化),这在您的情况下可以忽略不计。在任何情况下,基本模式是这样的:(在线程或 eventlet 协程中,您启动第二个进程,然后在其上 .communicate()/join()
。使用 eventlet.Timeout
或 Thread.join()
超时。如果超时触发, 使用 p.terminate()
或 p.kill()
停止当前计算。