1

我正在遍历一个列表并对列表的每个成员执行一些操作。如果一个成员花费了太多时间(在这种情况下为 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()
4

1 回答 1

1

Eventlet 是一个并发网络库...

目前尚不清楚功能expr2bddsatisfy_all功能是做什么的,但很可能它们只进行一些 CPU 计算而没有磁盘/网络 IO。在这种情况下,Eventlet 没有机会运行并触发超时异常。

如果您可以控制expr2bddsatisfy_all功能并且存在任何类型的循环,请eventlet.sleep(0)在每次迭代中放置。那是 Eventlet 习惯用法,用于“将控制权交给其他协程”,这就是将触发超时的地方。

如果您无法控制上述功能,第二好的选择是在一个单独的进程中运行它们,您可以强制终止该进程。在 POSIX 兼容的操作系统(例如 Linux、*BSD、OSX)上,您可以使用os.fork在单独的进程中运行一段代码。为了获得最大的便携性,请使用subprocess.Popen([sys.executable,...])multiprocessing.Process。后者提供了更高级别的 API,主要是围绕更容易的数据交换(序列化)而牺牲了性能开销,这在您的情况下可能可以忽略不计。无论如何,基本模式是这样的:(在线程或 eventlet 协程中,您启动第二个进程,然后.communicate()/join()在它上面。使用eventlet.TimeoutorThread.join()超时。如果超时触发,使用p.terminate()orp.kill()停止当前计算。

于 2015-05-12T14:25:04.970 回答