我实现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仍然有流程。
如果不是,我不理解GrimeLe能做什么,但是Python“协同程序”不能存在。
我的问题是
python coroutine(基于收益率)是真的吗(与其他的比较…lisp,ruby,&c)
如果正确的话,你能给我一些提示吗?

最佳答案

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处于休眠状态
gv2处于休眠状态
gv1.send(1)被调用,此操作将继续gv1
gv1进入gv2.send(1)
此恢复gv2
gv2进入gv1.send(1)
gv1正在恢复,但是,gv1自上次恢复以来尚未到达yield语句。所以,它还在运行,这就是为什么它也会抛出。
基本上,可以这样总结差异:
greenlet彼此共享一个固有的连接:.switch()暂停当前正在执行的greenlet,但将继续。
另一方面,发电机是完全独立的没有执行生成器的共享上下文。
yield将“暂停”生成器
next()/send()将恢复暂停的生成器,在运行生成器时调用它们将导致异常。
为什么要访问gv2(它代表test2的一个特定实例)?发电机test2()应该是独立的,不能对其使用方式做出任何假设。如果您决定要从其他作用域调用生成器,该怎么办无论如何,向自己传递价值观是没有任何意义的:你已经拥有了它们。

10-04 13:17