是否可以在多个消费者之间“流水线化”使用发电机?
例如,具有这种模式的代码很常见:
def consumer1(iterator):
for item in iterator:
foo(item)
def consumer2(iterator):
for item in iterator:
bar(item)
myiter = list(big_generator())
v1 = consumer1(myiter)
v2 = consumer2(myiter)
在这种情况下,多个函数完全使用同一个迭代器,因此需要将迭代器缓存在列表中。由于每个消费者都耗尽了迭代器,itertools.tee
所以没有用。
我经常看到这样的代码,我总是希望我能让消费者一次消费一个项目,而不是缓存整个迭代器。例如:
consumer1
消耗myiter[0]
consumer2
消耗myiter[0]
consumer1
消耗myiter[1]
consumer2
消耗myiter[1]
- ETC...
如果我要组成一个语法,它看起来像这样:
c1_retval, c2_retval = iforkjoin(big_generator(), (consumer1, consumer2))
您可以接近线程或多处理和tee
d 迭代器,但线程消耗的速度不同,这意味着缓存在内部的值 dequetee
可能会变得非常大。这里的重点不是利用并行性或加速任务,而是避免缓存迭代器的大部分。
在我看来,如果不修改消费者,这可能是不可能的,因为控制流在消费者手中。但是,当消费者实际使用迭代器时,控制权会传递到迭代器的next()
方法中,所以也许可以以某种方式反转控制流,以便迭代器一次阻塞消费者,直到它可以喂饱它们?
如果这是可能的,我还不够聪明,不知道怎么做。有任何想法吗?