【发布时间】:2019-06-13 13:21:48
【问题描述】:
当使用pool.map 调用方法函数时,我观察到一个非常奇怪的行为。
只有一个进程的行为与简单的 for 循环不同,我们在 if not self.seeded: 块中输入了多次,而我们不应该这样做。
这是下面的代码和输出:
import os
from multiprocessing import Pool
class MyClass(object):
def __init__(self):
self.seeded = False
print("Constructor of MyClass called")
def f(self, i):
print("f called with", i)
if not self.seeded:
print("PID : {}, id(self.seeded) : {}, self.seeded : {}".format(os.getpid(), id(self.seeded), self.seeded))
self.seeded = True
def multi_call_pool_map(self):
with Pool(processes=1) as pool:
print("multi_call_pool_map with {} processes...".format(pool._processes))
pool.map(self.f, range(10))
def multi_call_for_loop(self):
print("multi_call_for_loop ...")
list_res = []
for i in range(10):
list_res.append(self.f(i))
if __name__ == "__main__":
MyClass().multi_call_pool_map()
输出:
Constructor of MyClass called
multi_call_pool_map with 1 processes...
f called with 0
PID : 18248, id(self.seeded) : 1864747472, self.seeded : False
f called with 1
f called with 2
f called with 3
PID : 18248, id(self.seeded) : 1864747472, self.seeded : False
f called with 4
f called with 5
f called with 6
PID : 18248, id(self.seeded) : 1864747472, self.seeded : False
f called with 7
f called with 8
f called with 9
PID : 18248, id(self.seeded) : 1864747472, self.seeded : False
还有 for 循环:
if __name__ == "__main__":
MyClass().multi_call_for_loop()
输出:
Constructor of MyClass called
multi_call_for_loop ...
f called with 0
PID : 15840, id(self.seeded) : 1864747472, self.seeded : False
f called with 1
f called with 2
f called with 3
f called with 4
f called with 5
f called with 6
f called with 7
f called with 8
f called with 9
我们如何解释 pool.map 的行为(第一种情况)?我不明白为什么我们在 if 块中多次输入,因为 self.seeded 仅在构造函数中设置为 False 并且构造函数仅被调用一次......
(我有 Python 3.6.8)
【问题讨论】:
-
这是因为 Pool 将您的输入可迭代分块的方式。您的设置的块大小将是 3,在此处产生 [3,3,3,1] 块。您可以在我的答案here 中使用
calc_chunksize()计算它。
标签: python multiprocessing pool