无法使用python eventlet库超时(eventlet.timeout.Timeout)

时间:2015-05-11 10:34:38

标签: python python-3.x timeout try-catch eventlet

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

1 个答案:

答案 0 :(得分: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,主要围绕更容易的数据交换(序列化)而牺牲性能开销,这在您的情况下可以忽略不计。在任何情况下,基本模式是这样的:(在线程或事件小程序中,你启动第二个进程,然后.communicate()/join()就可以了。使用eventlet.TimeoutThread.join()超时。如果超时发生,使用p.terminate()p.kill()停止当前计算。