在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 (或者至少是禁止这种堆栈操作语言),这可能吗?(同样,不使用多线程)。
发布于 2015-06-25 05:16:40
它确实只在一个线程上运行。gevent使用greenlet,它是协程,而不是线程。每个给定时间只有一个堆栈(除非您使用多线程,然后在每个线程中使用greenlet)。
在上面的例子中,每当你调用sleep或joinall时,当前的协程(greenlet)实际上会让位于集线器。把集线器想象成一个中央调度器,负责决定下一步运行哪个协程。
为了让自己相信这一点,删除gevent.sleep(0)调用,您将看到它的行为有所不同。
请注意,与线程不同,执行是确定性的,因此如果您运行该程序两次,它将以完全相同的顺序执行。
https://stackoverflow.com/questions/30581965
复制相似问题