Code:
import gevent
import time
def func(a, t):
time.sleep(t)
print "got here", a
gevent.spawn(func, 'a', 4)
gevent.spawn(func, 'b', 0).join()
time.sleep(3)
print "exit"
Output:
got here a
got here b
exit
Expectation:
I never join on the first greenlet, so I expect that it will never execute; or, given the long sleep(), it should complete after the second greenlet.
Context:
I would like to be able to fire off a "throwaway" greenlet that populates a cache which I never join on and I never want to block to wait for the result of.
This is because time.sleep()
isn't gevent-aware, so when join()
is called, the execution flow will be:
gevent.spawn(a)
— pushes a "spawn a" operation onto the event queuegevent.spawn(b)
— pushes a "spawn b" operation onto the event queue.join()
— causes the main thread to yield and next event in the event queue is executed (in this case, a
)a
executes time.sleep(4)
, blocking the entire process for 4 seconds (but thread a
doesn't yield because time.sleep()
isn't gevent-aware)a
terminates and the next event in the event queue is executed (in this case, b
)b
executes and terminates, and the next event on the queue is executed (in this case, jumping back into the main thread, causing the .join()
to return)Use either gevent.monkey or gevent.sleep()
to see this perform as you'd expect.