【问题标题】:Plotting the pool map for multi processing Python为多处理 Python 绘制池图
【发布时间】:2021-07-03 21:36:45
【问题描述】:

如何使用 python 中的多处理工具运行多个进程池,在其中异步处理 run1-3。我正在尝试分别为run1,run2,run3 传递值(10,2,4),(55,6,8),(9,8,7)

import multiprocessing 
def Numbers(number,number2,divider):
   value = number * number2/divider
   return value
if __name__ == "__main__":

   with multiprocessing.Pool(3) as pool:               # 3 processes
        run1, run2, run3 = pool.map(Numbers, [(10,2,4),(55,6,8),(9,8,7)]) # map input & output

【问题讨论】:

    标签: python function asynchronous multiprocessing pool


    【解决方案1】:

    您只需要使用方法starmap 而不是map,根据文档:

    map() 类似,不同之处在于 iterable 的元素应该是解包为参数的可迭代对象。

    因此,[(1,2), (3, 4)]可迭代会导致[func(1,2), func(3,4)]

    import multiprocessing
    def Numbers(number,number2,divider):
       value = number * number2/divider
       return value
    if __name__ == "__main__":
    
       with multiprocessing.Pool(3) as pool:               # 3 processes
            run1, run2, run3 = pool.starmap(Numbers, [(10,2,4),(55,6,8),(9,8,7)]) # map input & output
       print(run1, run2, run3)
    

    打印:

    5.0 41.25 10.285714285714286
    

    注意

    这是做你想做的事情的正确方式,但是你不会发现对这样一个微不足道的工作函数使用多处理会提高性能;实际上,由于创建池以及将参数和结果从一个地址空间传递到另一个地址空间以及从另一个地址空间传递到另一个地址空间的开销,它会降低性能。

    【讨论】:

    【解决方案2】:

    然而,Python 的多处理库确实有一个用于在父进程和子进程之间传递数据的包装器,Manager 具有共享数据实用程序,例如共享字典。关于这个话题有一个很好的stack overflow post here

    使用多处理,您可以将唯一参数和共享字典传递给每个进程,并且您必须确保每个进程写入字典中的不同键。

    给定您的示例,使用中的示例如下:

    import multiprocessing
    
    
    def worker(process_key, return_dict, compute_array):
        """worker function"""
        number = compute_array[0]
        number2 = compute_array[1]
        divider = compute_array[2]
        return_dict[process_key] = number * number2/divider
    
    
    if __name__ == "__main__":
        manager = multiprocessing.Manager()
        return_dict = manager.dict()
        jobs = []
        compute_arrays = [[10, 2, 4], [55, 6, 8], [9, 8, 7]]
        for i in range(len(compute_arrays)):
            p = multiprocessing.Process(target=worker, args=(
                i, return_dict, compute_arrays[i]))
            jobs.append(p)
            p.start()
    
        for proc in jobs:
            proc.join()
        print(return_dict)
    

    编辑:来自 Booboo 的信息更加准确,我有一个关于线程的建议,我正在删除它,因为由于 GIL,它在 Python 中肯定不是正确的实用程序。

    【讨论】:

    • 您的解决方案是寻找正确问题的解决方案,但事实并非如此。当你有一个 100% 受 CPU 限制的工作函数时,线程从不是正确的方法,除非该函数是通过例如调用 C 语言函数来实现的释放全局解释器锁(GIL)。对于 OP 的困境,有一个 much 更简单的解决方案。 OP 的主要问题不是获取返回值,池是最简单的方法并且已经被使用。问题是如何简单地传递参数之一。 (...更多)
    • OP 可以手动将它们从列表中解压缩,而不必放弃使用池、更改工作函数的函数签名,然后不得不求助于使用托管 dict 来获取结果正如您的解决方案所要求的那样。但正如我所说,还有比手动从列表中解包参数更简单的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2021-07-24
    • 2020-08-14
    • 2016-11-10
    • 2013-12-01
    • 2017-04-18
    • 1970-01-01
    • 1970-01-01
    • 2015-01-13
    相关资源
    最近更新 更多