【问题标题】:What is offered by coroutines in python that improve a naive consumer/producer setup?python 中的协程提供了什么来改进幼稚的消费者/生产者设置?
【发布时间】:2011-08-06 08:57:05
【问题描述】:

我读过一些关于协程的文章,尤其是关于 python 的文章,但有些东西对我来说并不完全清楚。

我已经实现了一个生产者/消费者模型,其基本版本如下:

#!/usr/bin/env python

class MyConsumer(object):

    def __init__(self, name):
        self.__name = name

    def __call__(self, data):
        return self.observer(data)

    def observer(self, data):
        print self.__name + ': ' + str(data)

class MyProducer(object):

    def __init__(self):
        self.__observers = []
        self.__counter = 0

    def add_observer(self, observer):
        self.__observers.append(observer)

    def run(self):
        while self.__counter < 10:
            for each_observer in self.__observers:
                each_observer(self.__counter)

            self.__counter += 1

def main():

    consumer_one = MyConsumer('consumer one')
    consumer_two = MyConsumer('consumer two')
    producer = MyProducer()

    producer.add_observer(consumer_one)
    producer.add_observer(consumer_two)

    # run
    producer.run()

if __name__ == "__main__":
    main()

显然,MyConsumer 也可以具有用于生产的例程,因此可以轻松构建数据管道。正如我在实践中实现的那样,定义了一个实现消费者/生产者模型逻辑的基类,并实现了在子类中覆盖的单个处理功能。这使得生成具有易于定义、隔离的处理元素的数据管道变得非常简单。

在我看来,这是为协程提供的典型应用程序类型,例如在经常引用的教程中:http://www.dabeaz.com/coroutines/index.html。不幸的是,对我来说,协程相对于上面的实现有什么优势并不明显。我可以看到,在可调用对象更难处理的语言中,有一些收获,但在 python 的情况下,这似乎不是问题。

有人可以帮我解释一下吗?谢谢。

edit:抱歉,上面代码中的生产者从0到9计数并通知消费者,然后打印出他们的名字和计数值。

【问题讨论】:

  • 第一个问题的出色工作!谢谢!

标签: python producer-consumer coroutine observer-pattern


【解决方案1】:

使用协程方法时,消费者和生产者的代码有时会更简单。在您的方法中,其中至少一个必须写为有限状态机(假设涉及某些状态)。

使用协程方法,它们本质上是独立的进程。

举个例子会有所帮助:

以您提供的示例为例,但现在假设消费者只打印每第二个输入。您的方法需要添加一个对象成员,指示接收到的输入是奇数还是偶数样本。

def observer(self, data):
    self.odd_sample = !self.odd_sample
    if self.odd_sample:
        print str(data)

使用协程时,只需循环输入,每秒丢弃一次输入。 “状态”由代码中的当前位置隐式维护:

while True:
    y = producer()
    print(y)
    y = producer()
    # ignore this value

【讨论】:

  • 啊,我明白了。可以说优势具有这种性质吗?没有根本的“应该这样做”的理由吗?特别是,我可能拥有的任何状态依赖都将依赖于运行时,因此无论如何它都需要与协程中的逻辑相关联。
  • 已经有很多方法可以使用消费者/生产者范式来做事,以至于没有“应该这样做”。考虑您是否需要多线程、多处理或两者都需要,应该可以帮助您确定最适合您的方式。完成工作的最简单方法通常(通常!)是最好的方法。
猜你喜欢
  • 2015-11-17
  • 1970-01-01
  • 2019-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多