在 python 中了解使用协程的生产者和接收者

Understand the producer and receiver using coroutine in python

我想用协程实现producer和receiver。我的想法是使用两个协程,一个用于生产者,一个用于接收者。但是我对协程的 send 和 运行 模式的理解是错误的。这是我的代码:

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

class Producer(object):
    def __init__(self, recevier):
        self.count=1
        self.producer_coroutine = self._producer()
        self.receiver = receiver

    @coroutine
    def _producer(self):
        print "Waiting"
        yield

        while True:
            self.send("Yeah, but no, but yeah, but no")
            get_feedback =  (yield )
            print ("get feedback %s"%get_feedback)
            self.send("A series of tubes")
            break

    def send(self,arg):
        self.receiver.receive_coroutine.send(arg)

    def init_producer(self):
         self.producer_coroutine.send("begin the send and receive")

class Recevier(object):
    def __init__(self):
        self.count=1
        self.receive_coroutine=self._rececive()
        self.producer = None

    def setting_producer(self, producer):
        self.producer = producer

    @coroutine
    def _rececive(self):
        while True:
            line = (yield)
            print("Get line is : %s" %line)
            self.feedback("Got it")

    def feedback(self, arg):
        self.producer.producer_coroutine.send(arg)


receiver = Recevier()
producer = Producer(receiver)
receiver.setting_producer(producer)
producer.init_producer()

Python给我报错:

Waiting
Get line is : Yeah, but no, but yeah, but no
Traceback (most recent call last):
  File "test/test_coroutine.py", line 56, in <module>
    producer.init_producer()
  File "test/test_coroutine.py", line 31, in init_producer
    self.producer_coroutine.send("begin the send and receive")
  File "test/test_coroutine.py", line 21, in _producer
    self.send("Yeah, but no, but yeah, but no")
  File "test/test_coroutine.py", line 28, in send
    self.receiver.receive_coroutine.send(arg)
  File "test/test_coroutine.py", line 47, in _rececive
    self.feedback("Got it")
  File "test/test_coroutine.py", line 50, in feedback
    self.producer.producer_coroutine.send(arg)
ValueError: generator already executing

更新:我发现greenlet可以实现通信。像这样:

from greenlet import greenlet

def test1():
    global a
    print 12, "begin switch"
    gr2.switch()
    a = 4
    print " begin  switch too"
    gr2.switch()

def test2():

    global a
    print 56,"come from test1, to swich"
    gr1.switch()
    print a
    print 78

a=5
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

当您调用 producer.init_producer() 时,会发生以下情况:

  • _producer 发送 "Yeah, but no, but yeah, but no".
  • _rececive 收到 "Yeah, but no, but yeah, but no" 并打印它。
  • _rececive 呼叫 self.feedback.
  • self.feedback 发送 "Got it"_producer
  • 但是,_producer 仍然在 self.send("Yeah, but no, but yeah, but no") 行,因为 _rececive 还没有 yielded。
  • 由于 _producer 不在 yield 语句中,它无法接收发送,因此抛出异常。

因此,问题出在您的反馈循环上。我不确定为什么需要反馈循环,就像您注释掉 send_feedbackget_feedback 行一样,程序运行正常,生成:

Waiting
Get line is : Yeah, but no, but yeah, but no
Get line is : A series of tubes
Traceback (most recent call last):
  File "d.py", line 58, in <module>
    producer.init_producer()
  File "d.py", line 32, in init_producer
    self.producer_coroutine.send("begin the send and receive")
StopIteration