python - 没有返回值的多处理池?

标签 python python-3.x multiprocessing python-multithreading

我正在尝试使用没有返回值的多处理 Pool 进行并行计算。如果不需要从子进程返回和检索值,它可能会更快。有办法吗?

这是一个简单的例子:

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]

有人知道为什么吗?有解决方案吗?

最佳答案

你的函数有趣

def fun(a):
    # do something.. 
    a["1"]=100

改变可变参数a。但是,当您使用 p.map(fun, multi) 调用它时,multi 列表中的每个项目都会被 pickle,发送到工作进程并在那里发生变异。这不会对调用过程中列表中的原始项目产生任何影响。

您可以创建可以在进程之间共享的数据结构,即所谓的proxy objects , 使用 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 开销,如果可以的话,可能会比仅使用函数的返回值更糟糕。

关于python - 没有返回值的多处理池?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47797091/

相关文章:

python - 如何使用线程/多处理来防止程序挂起?

Python-PPTX : Data Label Positions not working for Doughnut Chart

python - 如何在python的scrapy中删除字符串的特定部分

python - 为什么我要将 python 添加到 PATH

python - Cassandra 多处理无法 pickle _thread.lock 对象

perl 进程队列

python - 如何使用自定义 IO 函数扩展 Pandas?

python - 函数内的字典值和列表值

json - Python 在读取 JSON 文件时抛出错误

python - 如何将一列连接到不是 None 的 pandas 列表的现有列中?