在gevent tutorial中有一个示例如下:
import gevent
def foo():
print('Running in foo')
gevent.sleep(0)
print('Explicit context switch to foo again')
def bar():
print('Explicit context to bar')
gevent.sleep(0)
print('Implicit context switch back to bar')
gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
])
,输出
Running in foo
Explicit context to bar
Explicit context switch to foo again
Implicit context switch back to bar
我对它进行了测试,并亲眼看到它有效。我的一位朋友声称这完全在一个线程内运行。除了我无法想到gevent.sleep(0)的任何实现,它并没有归结为某种形式的欺骗" (即:交换前两个堆栈帧等。)
有人可以解释这是如何工作的吗?如果这是Java(或至少某种禁止这种堆栈操作的语言),这可能吗? (再次,不使用多个线程)。
答案 0 :(得分:0)
它确实只在1个线程上运行。 gevent使用greenlets,它们是协程,而不是线程。每个给定时间只有1个堆栈(除非您使用多线程,然后在每个线程中使用greenlet)。
在上面的示例中,无论何时调用sleep或joinall,当前的协程(greenlet)实际上都会产生到集线器。将中心视为中央调度员,负责决定下一步将运行哪个协程。
为了说服自己,删除gevent.sleep(0)调用,你会发现它的行为不同。
请注意,与线程不同,执行是确定性的,因此如果您运行程序两次,它将以完全相同的顺序执行。