简体   繁体   中英

Why does gevent execute this unjoined greenlet?

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:

  1. gevent.spawn(a) — pushes a "spawn a" operation onto the event queue
  2. gevent.spawn(b) — pushes a "spawn b" operation onto the event queue
  3. .join() — causes the main thread to yield and next event in the event queue is executed (in this case, a )
  4. 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)
  5. a terminates and the next event in the event queue is executed (in this case, b )
  6. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM