是否有可能跨越多個消費者「管道」發電機的消耗?將一個迭代器傳遞給多個消費者?
例如,它是常見的有代碼與該圖案:
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]
- 等...
如果我是馬磕了一個語法,它應該是這樣的:
c1_retval, c2_retval = iforkjoin(big_generator(), (consumer1, consumer2))
你可以親近與螺紋或多核和tee
d迭代器,但線程以不同的速度意味着雙端隊列緩存內tee
值可以得到非常大的消耗。這裏的重點不在於利用並行性或加速任務,而是爲了避免緩存大部分迭代器。
在我看來,如果不修改消費者,這可能是不可能的,因爲控制流程在消費者中。然而,當一個消費者實際使用迭代器控制進入迭代器的方法時,所以也許有可能以某種方式反轉控制流,以便迭代器一次一個地阻止消費者,直到它可以提供所有消費者爲止。
如果這是可能的,我不夠聰明,看看如何。有任何想法嗎?
如果這個觀點不一定是並行性,那麼一種可能性就是集中迭代器,並將數據發送給每個* consumer *,也許使用一個帶有'position%task'列表的類,該列表返回每個'產量「呼叫。 – Rubens 2013-03-24 03:58:09
也許這可以通過協程來完成?如果您有一箇中央迭代器,它將項目發送給單個協程,那麼可以獲得您想要的內容。無論如何,我認爲你應該檢查節省的內存是否很重要,因爲事情會變得複雜。我個人會簡單地使用'myiter = list(the_generator())'並傳遞序列。 – Bakuriu 2013-03-24 12:09:25