采用这个示例程序:
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
def fun(xx):
for _ in range(10):
y = 1
x = xx
while x > 0:
y = (y * x) % 1000000007
x -= 1
print("END {}! = {}".format(xx, y))
return xx, y
with ThreadPoolExecutor(max_workers=8) as executor:
out = executor.map(fun, range(10000))
for x in out:
print(x)
这让我可以看到每次实际计算函数时打印的消息,以及从输出生成器中读取输出时的消息。人们应该期望功能消息不是严格按顺序排列,而生成器是。此外,我希望生成器为我提供“作为管道”的数据,在处理整个输入之前给出中间结果。这可能是我正在处理的无限流。
如果我使用ProcessPoolExecutor
,这就像我预期的那样工作,我很快就可以在线程池创建新结果时从输出生成器开始读取。另一方面,使用ThreadPoolExecutor
,虽然它似乎工作正常,但它只在很多函数执行已经发生后才开始向我提供输出。例如:
END 6363! = 280520285
END 6364! = 231081245
END 6365! = 832114135
END 6366! = 238546331
(0, 1)
(1, 1)
(2, 2)
(3, 6)
(4, 24)
END 6368! = 281286418
END 6369! = 513183705
END 6370! = 980177974
为什么会有这么大的差异,我该如何控制这种行为?如果我想使用线程,并且我想确保我的结果更快,我应该自己分块数据而不是依赖map
吗?
答案 0 :(得分:0)
你在ProcessPoolExecutor中获得更快结果的一个原因是它产生了一大块迭代器,因此每个块都会进入cpu的核心(你指定的worker的数量),并且该核心可能会更快地完成其块的计算,并且它可以更进一步并执行你的for循环