我在列表上循环并在列表的每个成员上执行一些操作。如果成员花费太多时间(在这种情况下为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是一个并发网络库...
尚不清楚expr2bdd
和satisfy_all
功能的功能,但很可能仅执行一些CPU计算,而没有磁盘/网络IO。在这种情况下
如果您控制了expr2bdd
和satisfy_all
功能,并且有任何类型的循环,则将eventlet.sleep(0)
放置在每次迭代中。这是"屈服对其他coroutines的收益控制"的习语,这就是暂停的地方。
如果您无法控制上述功能,那么第二的最佳选择是在单独的过程中运行它们,您可以强行杀死。在POSIX兼容OS(例如Linux, *BSD,OSX)上,您可以使用os.fork
在单独的过程中运行一块代码。为了获得最大的可移植性,请使用subprocess.Popen([sys.executable,...])
或multiprocessing.Process
。后者以较高的API给出了更高的API,主要围绕更轻松的数据交换(序列化),而绩效开销成本可能可以忽略不计。无论如何,基本模式是:(在线程或Eventlet coroutine中,您可以启动第二个进程,然后在其上进行.communicate()/join()
。使用 eventlet.Timeout
或 Thread.join()
进行超时。如果超时触发,请使用p.terminate()
或p.kill()
停止当前计算。