我正在循环一个列表并对列表中的每个成员执行一些操作。
如果某个成员花费了太多时间(在本例中为 1 秒),我打算跳过它。但是,try
语句内的 block 始终处于处理状态,并且永远不会超时。我不明白为什么。
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 计算,而不进行磁盘/网络 IO。在这种情况下,Eventlet 没有机会运行并引发超时异常。
如果您可以控制 expr2bdd
和 satisfy_all
函数并且存在任何类型的循环,请将 eventlet.sleep(0)
放置在每个函数处迭代。这是 Eventlet 惯用语,意思是“将控制权交给其他协程”,这就是超时将被触发的地方。
如果您无法控制上述函数,第二个最佳选择是在可以强制终止的单独进程中运行它们。在 POSIX 兼容操作系统(例如 Linux、*BSD、OSX)上,您可以使用 os.fork 在单独的进程中运行一段代码。为了获得最大的可移植性,请使用 subprocess.Popen([sys.executable,...])
或 multiprocessing.Process
。后者提供了更高级别的 API,主要围绕更容易的数据交换(序列化),但以性能开销为代价,这在您的情况下可能可以忽略不计。无论如何,基本模式是这样的:(在线程或 eventlet 协程中,您启动第二个进程,然后对其进行 .communicate()/join()
。使用 eventlet.Timeout
或 Thread.join()
带有超时。如果超时,请使用 p.terminate()
或 p.kill()
停止当前计算。
关于python - 无法使用 python eventlet 库超时(eventlet.timeout.Timeout),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30165465/