我正在实施greenlet API。
from greenlet import greenlet
def test1():
print 12
gr2.switch()
print 34
def test2():
print 56
gr1.switch()
print 78
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()
这是我凌乱的代码
def test1():
tmp1=yield
print 12
try:
gv2.send(1)
except StopIteration:
pass
tmp1=yield
print 34
def test2():
tmp2=yield
print 56
try:
gv2.send(1)
except StopIteration:
pass
tmp1=yield
print 78
gv1=test1()
gv1.next()
gv2=test2()
gv2.next()
gv1.send(1)
节目,
12
56
Traceback (most recent call last):
File "prog.py", line 26, in <module>
gv1.send(1)
File "prog.py", line 5, in test1
gv2.send(1)
File "prog.py", line 15, in test2
gv2.send(1)
ValueError: generator already executing
所以,我不知道我猜对了,
但看起来在test1发送'1'到test2之后,它仍然有一些东西,
与gevent不同,没有控制流切换发生。 test1仍有流量。
如果没有,我不明白greenlet可以做什么,但python“coroutine”不存在。
我的问题是
答案 0 :(得分:7)
test2()
的生成器实例正在向自身发送值。
def test2():
tmp2=yield
print 56
try:
gv2.send(1) # this is the offending line
except StopIteration:
pass
tmp1=yield
print 78
send()
将恢复生成器,但只要代码在test2()
内执行,它就已经在运行。这就是它抛出的原因。
你想做的事:gv1.send(1)
?这也行不通。
原因如下:
gv1.send(1)
之前
gv1.send(1)
被调用,这将恢复gv1
gv1
前往gv2.send(1)
gv2
gv2
前往gv1.send(1)
gv1
正在恢复,然而,gv1
自上次恢复以来尚未达到yield
语句。因此,它仍在运行,这就是为什么它也会抛出。基本上,差异可以概括为:
.switch()
暂停当前正在执行的greenlet,然后将恢复。yield
将“暂停”生成器next()
/ send()
将恢复暂停的生成器,在正在运行的生成器上调用它们将导致异常。为什么要访问gv2
(代表一个特定的 test2
实例)?生成器test2()
应该是自包含的,不对它的使用方式做任何假设。如果您决定要从其他范围调用生成器,该怎么办?无论如何,向自己发送价值是没有任何意义的:你已经拥有它们。