没有 return 值的多处理池?
multiprocessing Pool without return value?
我正在尝试使用没有 return 值的多处理 Pool
进行并行计算。如果不需要 return 并从子进程中检索值,它可能会更快。有办法吗?
这是一个简单的例子:
from multiprocessing import Pool
def fun(a):
# do something..
a["1"]=100
a={
"1":12
}
multi = [a] * 10
p = Pool(4)
p.map(fun, multi)
data = [a["1"] for a in multi]
print(data)
>>> [12, 12, 12, 12, 12, 12, 12, 12, 12, 12]
[fun(a) for a in multi]
data = [a["1"] for a in multi]
print(data)
>>> [100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
有人知道为什么吗?有解决方案吗?
你的函数fun
def fun(a):
# do something..
a["1"]=100
更改可变参数 a
。但是,当您使用 p.map(fun, multi)
调用它时, multi
列表中的每个项目都会被腌制,发送到工作进程并在那里发生变异。这对调用过程中列表中的原始项目没有任何影响。
您可以创建可在进程之间共享的数据结构,即所谓的 proxy objects, using managers。您必须创建 10 个共享词典。在您的示例中,您只有一个字典,该列表包含 10 个对它的引用,data = [a["1"] for a in multi]
将始终只包含相同的值,因为 a
始终是相同的对象。
所以这应该有效:
from multiprocessing import Pool, Manager
import random
def fun(a):
# to show that the dictionaries are different
a["1"] = random.random()
if __name__ == '__main__':
m = Manager()
p = Pool(4)
multi = [m.dict() for _ in range(10)]
p.map(fun, multi)
data = [a["1"] for a in multi]
print(data)
请注意,multi = m.list([a] * 10)
或类似的方法将不起作用,因为只有列表访问是同步的,而不是包含元素的更新。但是所有这些都会产生额外的 IPC 开销,如果可以的话,可能会比仅使用函数的 return 值更糟糕。
我正在尝试使用没有 return 值的多处理 Pool
进行并行计算。如果不需要 return 并从子进程中检索值,它可能会更快。有办法吗?
这是一个简单的例子:
from multiprocessing import Pool
def fun(a):
# do something..
a["1"]=100
a={
"1":12
}
multi = [a] * 10
p = Pool(4)
p.map(fun, multi)
data = [a["1"] for a in multi]
print(data)
>>> [12, 12, 12, 12, 12, 12, 12, 12, 12, 12]
[fun(a) for a in multi]
data = [a["1"] for a in multi]
print(data)
>>> [100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
有人知道为什么吗?有解决方案吗?
你的函数fun
def fun(a):
# do something..
a["1"]=100
更改可变参数 a
。但是,当您使用 p.map(fun, multi)
调用它时, multi
列表中的每个项目都会被腌制,发送到工作进程并在那里发生变异。这对调用过程中列表中的原始项目没有任何影响。
您可以创建可在进程之间共享的数据结构,即所谓的 proxy objects, using managers。您必须创建 10 个共享词典。在您的示例中,您只有一个字典,该列表包含 10 个对它的引用,data = [a["1"] for a in multi]
将始终只包含相同的值,因为 a
始终是相同的对象。
所以这应该有效:
from multiprocessing import Pool, Manager
import random
def fun(a):
# to show that the dictionaries are different
a["1"] = random.random()
if __name__ == '__main__':
m = Manager()
p = Pool(4)
multi = [m.dict() for _ in range(10)]
p.map(fun, multi)
data = [a["1"] for a in multi]
print(data)
请注意,multi = m.list([a] * 10)
或类似的方法将不起作用,因为只有列表访问是同步的,而不是包含元素的更新。但是所有这些都会产生额外的 IPC 开销,如果可以的话,可能会比仅使用函数的 return 值更糟糕。