我希望听到其他人解决问题的方法,我以默认方式看到gevent用来向退出状态发送信号给greenlet。
我喜欢做group.kill(timeout = 3)的能力,但它在greenlet中翻译的方式是生成GreenletExit。这对于非常简单的本地计算代码来说很好,但我发现它对于任何更复杂的东西都是非常有限的。这是一个例子(使用ZMQ):
def myGreenlet( zFrom, zTo ):
msg = zFrom.recv_multipart()
zTo.send_multipart( msg )
我希望能够告诉我的greenlet退出,但如果它正在接收/传输任何内容,则忽略GreenletExit。如果是这种情况,请发送您收到的任何消息,然后才能彻底退出。
GreenletExit只是一家中国商店的公牛。因此,我提出的解决方案是不使用该机制,而不是作为最后的资源,而是我手动处理信号到greenlet通过这样的事件退出:
def myGreenlet( stopEvent, zFrom, zTo ):
while not stopEvent.wait( 0 ):
msg = zFrom.recv_multipart()
zTo.send_multipart( msg )
正如您所注意到的,除非我开始在所有IO调用中添加超时(如recv)并在.wait()中添加超时以减慢速度,否则这不是很好,这是对的gevent哲学。
我已经找到了更好的解决方案,但没有运气。什么是普遍的共识,这种问题的任何良好支持的方法?
答案 0 :(得分:0)
更明智的解决方法可能是让每个greenlet处理自己的超时异常。 greenlet协调员不应对greenlets进行太多干预。协调员应该做的是joinall
,然后向greenlets询问结果或异常,然后依赖于做一些后续行动。
详细解释:
def my_greenlet():
try:
# do something here...
except KindOfTimeOutException, e:
raise e
greenlets协调员:
greenlets = [gevent.spawn(my_greenlet) for i range(10)]
gevent.joinall(greenlets)
# NOTE: On this time, the greenlets all have quit by themselves
for greenlet in greenlets:
e = greenlet.exception
if e:
# handle exception...
else:
result = greenlet.value
# do something...