【问题标题】:Understand the producer and receiver using coroutine in python在python中使用协程了解生产者和接收者
【发布时间】:2015-04-01 14:36:14
【问题描述】:

我想用协程来实现生产者和接收者。我的想法是使用两个协程,一个用于生产者,一个用于接收者。但是我对协程的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()

【问题讨论】:

    标签: python generator producer-consumer coroutine


    【解决方案1】:

    当您拨打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
    

    【讨论】:

    • 在某些情况下,我希望receiver可以让producer启动,这样producer可以继续,就像greenlet switch一样。以任何方式解释我的代码失败的原因。我想知道为什么 _producer 仍然在线 self.send ?它可以发送并转到下一行吗?这似乎是合理的,它是一个协程并发送一些东西,应该继续。
    • @jiamo 不,它发送并等待发送完成,正如我在上面解释的那样,这永远不会发生。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 2011-08-06
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 2013-11-10
    相关资源
    最近更新 更多