为什么gevent.spawn直到调用Greenlet.join才执行带参数的函数?

9
我想使用gevent发出异步的HTTP POST请求 -- 我不关心响应,我只是想尽快执行该请求。然而,每当我尝试使用gevent.spawn这样做时,该请求从未执行。我知道这是因为在gevent.spawn返回的Greenlet上调用.ready().successful()方法总是返回False
然而,Greenlet确实已经开始了,因为如果我调用glet = gevent.spawn(...),然后glet.start(),我会得到一个错误,说AssertionError:Greenlet already started
唯一能让glet.ready() == True的时候是当我调用glet.join()时,但这是一个阻塞操作。如何让Greenlet在不等待完成的情况下执行?
1个回答

9
由于greenlet是协作式的,新的greenlet在您yield给它之前不会运行。 在调用spawn之后,调用gevent.sleep(0)以yield,这样您的greenlet应该运行。
它将继续运行,直到执行某些导致它yield(例如启动http req)的操作。 然后,您的其他代码可以再次恢复。
编辑:
针对您关于grequests的问题,grequests.send()文档如下:
send(r, pool=None, stream=False)
    Sends the request object using the specified pool. If a pool isn't
    specified this method blocks. Pools are useful because you can specify size
    and can hence limit concurrency

由于您没有指定池,请求会阻塞等待您的greenlet完成。换句话说,一旦它返回,greenlet就已经完成。要获取响应,请参见返回的greenlet的glt.get()


啊,看起来好像可以工作了!但是,当我使用grequests(https://github.com/kennethreitz/grequests)库时,调用grequests.send(grequests.request("POST", <url>))会创建一个Greenlet,但即使调用gevent.sleep(),这个Greenlet也不会执行。你知道为什么吗? - neptune

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接