为什么gevent执行这个未加入的greenlet?

ʞɔı*_*ɔıu 3 python multithreading gevent greenlets

码:

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"
Run Code Online (Sandbox Code Playgroud)

输出:

got here a
got here b
exit
Run Code Online (Sandbox Code Playgroud)

期望:

我从不加入第一个greenlet,所以我希望它永远不会执行; 或者,如果长睡眠(),它应该在第二个greenlet之后完成.

语境:

我希望能够启动一个"一次性"greenlet填充缓存,我永远不会加入,我永远不想阻止等待结果.

Dav*_*ver 5

这是因为time.sleep()不是gevent-aware,所以在join()调用时,执行流程将是:

  1. gevent.spawn(a) - 将"spawn a"操作推送到事件队列
  2. gevent.spawn(b) - 将"spawn b"操作推送到事件队列
  3. .join()- 导致主线程产生并执行事件队列中的下一个事件(在本例中a)
  4. a执行time.sleep(4),阻止整个过程4秒(但线程a不会产生因为time.sleep()不是gevent-aware)
  5. a终止并执行事件队列中的下一个事件(在本例中b)
  6. b执行并终止,并执行队列中的下一个事件(在这种情况下,跳回主线程,导致.join()返回)

使用gevent.monkeygevent.sleep()看到这个按预期执行.