无法使用 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...

不清楚 expr2bddsatisfy_all 函数的作用,但很可能它们只进行一些 CPU 计算而没有 disk/network IO。在这种情况下,Eventlet 没有机会 运行 并触发超时异常。

如果您可以控制 expr2bddsatisfy_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.TimeoutThread.join() 超时。如果超时触发, 使用 p.terminate()p.kill() 停止当前计算。