如何实现可并发填充且可复用的特殊Iterable?
并发迭代器实现需求
我有一个以IO密集方式获取或生成“对象”(如网页数据、摄像头图像等)的函数,还有一个以CPU密集方式处理这些对象的函数。以下是现有实现示例:
import time def make_things(n_things) -> list: things = [] for i in range(n_things): # 模拟IO密集操作 time.sleep(1) things.append(i) return things def do_something_with_things(things: list): for thing in things: # 模拟CPU密集操作 start_cpu_bound = time.time() while time.time() - start_cpu_bound < 1: _ = 1 + 1 print(f"{time.time() - start_time:.1f}", f"#{thing}") start_time = time.time() things = make_things(2) do_something_with_things(things) print(f"Total time: {time.time() - start_time:.1f}")
该示例执行后输出:
3.0 #0 4.0 #1 Total time: 4.0
当前逻辑是先生成所有对象,再逐个处理,我需要实现边生成边处理的并发执行模式,同时满足以下两个要求:
- 尽量保留处理函数的原有逻辑,仅允许将其参数类型从
list改为可迭代对象(iterable); - 首次遍历完成后,该迭代器需缓存所有对象,可像普通列表一样重复遍历。
换句话说,需要实现一种特殊迭代器,行为如下:
# 循环会等待下一个可用项,或在迭代器完成时退出: for item in special_iterable: # 填充迭代器的IO密集任务仍在后台运行,准备下一项(无剩余则停止) # 此处执行CPU密集操作 # 所有操作完成后,迭代器已缓存所有值,可像普通列表一样重复遍历 for item in special_iterable: # 直接访问之前的所有项
补充说明:无需等到首次遍历才开始填充迭代器,可提前创建迭代器,在执行其他CPU密集任务的同时后台填充;遍历时代码会自动等待未就绪的对象,全部完成后可快速复用:
iterable = make_iterable_somehow() # 包含10个项,每个获取/生成需1秒 # 执行耗时5秒的CPU密集任务 # 前5个项可快速遍历,后5个项需逐个等待1秒 for item in iterable: # 耗时极短的操作 # 可快速遍历所有项 for item in iterable: # 耗时极短的操作
内容的提问来源于stack exchange,提问作者Alexander Soare
相关产品推荐
相关产品推荐

