为什么gevent会执行这个未加入的绿色线程?

3 投票
1 回答
725 浏览
提问于 2025-04-17 17:37

代码:

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"

输出:

got here a
got here b
exit

期望:

我从来不去等待第一个绿色线程(greenlet),所以我希望它永远不会执行;或者,由于有很长的 sleep(),它应该在第二个绿色线程完成后才结束。

背景:

我想能够启动一个“临时”的绿色线程,用来填充一个缓存,而我从来不去等待它的结果,也不想被它阻塞。

1 个回答

5

这是因为 time.sleep() 并不支持 gevent,所以当你调用 join() 时,执行的流程会是这样的:

  1. gevent.spawn(a) — 把一个“启动 a”的操作放到事件队列里
  2. gevent.spawn(b) — 把一个“启动 b”的操作也放到事件队列里
  3. .join() — 让主线程暂停,接下来执行事件队列中的下一个事件(在这个例子中是 a
  4. a 开始执行 time.sleep(4),这会让整个程序停顿 4 秒(但线程 a 不会暂停,因为 time.sleep() 不支持 gevent)
  5. a 执行完毕,接下来执行事件队列中的下一个事件(在这个例子中是 b
  6. b 执行完并结束,接下来执行队列中的下一个事件(这时又回到主线程,导致 .join() 返回)

使用 gevent.monkeygevent.sleep() 可以让你看到预期的效果。

撰写回答