常规尾纺

时间:2013-05-24 10:31:24

标签: python

我可以连接两个协程A和B,A会激发B而B会激发A吗?例如,A接受一个数字,打印它并用(数字+ 1)调用B. B将打印它并使用(数字+ 1)调用A.我希望1,2,3,4,5,...打印

遗憾的是,此代码确实可以正常运行

def coroutine(func):
    def start(*args,**kwargs):
        cr = func(*args,**kwargs)
        cr.next()
        return cr
    return start

_target_from_a = None
_target_from_b = None

@coroutine
def func_a():
    while True:
        item = yield
        print 'a', item
        _target_from_a.send(item + 1)

@coroutine
def func_b():
    while True:
        item = yield
        print 'b', item
        _target_from_b.send(item + 1)

a = func_a()
b = func_b()
_target_from_a = b
_target_from_b = a

a.send(1)

它产生了跟随error

a 1
b 2
Traceback (most recent call last):
  File "coloop.py", line 31, in <module>
    a.send(1)
  File "coloop.py", line 17, in func_a
    _target_from_a.send(item + 1)
  File "coloop.py", line 24, in func_b
    _target_from_b.send(item + 1)
ValueError: generator already executing

1 个答案:

答案 0 :(得分:2)

_target_from_a.send(something)执行a {/ 1}}协程之后,yield 调用b“暂停”后恢复执行,以及它是什么确实是:

    item = yield
    print 'b', item
    _target_from_b.send(item + 1)   # ARGH!!

问题是_target_from_b.send(item + 1)会尝试拨打a。但是a在这一瞬间并没有等待任何事情,它仍然在执行。

请记住,协程在执行时就像任何其他函数一样。调用_target_from_a.send()使暂停协程,但是python只是执行函数调用。

摘要:从不使用协同程序制作循环。他们根本无法工作。

请注意,从多个线程访问相同的生成器/协同程序时,也可能会引发generator already executing异常。


我建议你阅读"A Curious Course on Coroutines and Concurrency" David Beazley,他解释了如何使用协同程序以及它们如何工作。