问题
I have two functions that receives data from two different connections, and i should close both connections after getting result from one of them.
def first():
gevent.sleep(randint(1, 100)) # i don't know how much time it will work
return 'foo'
def second():
gevent.sleep(randint(1, 100)) # i don't know how much time it will work
return 'bar'
Then i spawn each function:
lst = [gevent.spawn(first), gevent.spawn(second)]
gevent.joinall
blocks current greenlet until both two greenlets from lst
are ready.
gevent.joinall(lst) # wait much time
print lst[0].get(block=False) # -> 'foo'
print lst[1].get(block=False) # -> 'bar'
I want to wait until eiter first or second greenlet become ready:
i_want_such_function(lst) # returns after few seconds
print lst[0].get(block=False) # -> 'foo' because this greenlet is ready
print lst[1].get(block=False) # -> raised Timeout because this greenlet is not ready
How can i do it?
回答1:
You could use gevent.event.Event (or AsyncResult) and Greenlet's link() method, like this:
...
ready = gevent.event.Event()
ready.clear()
def callback():
ready.set()
lst = [gevent.spawn(first), gevent.spawn(second)]
for g in lst:
g.link(callback)
ready.wait()
...
回答2:
callback receives gevent child process and you can get e.g. return value from it
...
cars = []
def _callback(job):
cars.append(job.value)
for car in xml_all_cars:
print "creating jobs"
g_parse = Greenlet.spawn(myMainFunction)
g_parse.start()
g_parse.link(_callback)
jobs.append(g_parse)
print "starting all jobs"
gevent.joinall(jobs)
print "jobs done"
return cars
cars will have list of all values that myMainFunction returns (for every car)
来源:https://stackoverflow.com/questions/13579005/wait-until-one-of-several-greenlets-finished