问题描述
|
我已经读过一些有关协程的知识,特别是关于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,这似乎不是问题。
有人可以帮我一下吗?谢谢。
编辑:抱歉,上面代码中的生产者从0到9进行计数,并通知消费者,消费者随后打印出他们的名字和计数值。
解决方法
使用协程方法时,有时消费者和生产者代码都可能更简单。在您的方法中,必须至少将其中之一编写为有限状态机(假设涉及某种状态)。
使用协程方法,它们本质上是独立的过程。
一个例子会有所帮助:
以您提供的示例为例,但现在假设使用者仅在第二次输入时打印。您的方法需要添加一个对象成员,以指示接收到的输入是奇数还是偶数样本。
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