2

A が B を励起し、B が A を励起する 2 つのコルーチン A と B を接続できますか? たとえば、A は数値を受け取り、それを出力して、(number+1) で B を呼び出します。B はそれを印刷し、(number+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)

次のエラーが発生します。

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
4

1 に答える 1

2

コルーチンを実行_target_from_a.send(something)すると、実行を再開する呼び出しによって「一時停止」される前に、次のようになります。ayieldb

    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複数のスレッドから同じジェネレーター/コルーチンにアクセスするときにも例外が発生する可能性があることに注意してください。


David Beazley による「A Curious Course on Coroutines and Concurrency」を読むことをお勧めします。彼は、コルーチンの使用方法とその動作方法を非常によく説明しています。

于 2013-05-24T11:04:57.550 に答える