gevent clean Greenlet退出

时间:2015-05-21 12:28:44

标签: python gevent

我希望听到其他人解决问题的方法,我以默认方式看到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哲学。

我已经找到了更好的解决方案,但没有运气。什么是普遍的共识,这种问题的任何良好支持的方法?

1 个答案:

答案 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...