繁体   English   中英

使用Pool进行Python多处理-主过程永远需要

[英]Python multiprocessing with Pool - the main process takes forever

我试图了解多处理如何与Python一起工作。 这是我的测试代码:

import numpy as np
import multiprocessing
import time

def worker(a):
    for i in range(len(a)):
        for j in arr2:
            a[i] = a[i]*j
    return len(a)

arr2 = np.random.rand(10000).tolist()

if __name__ == '__main__':
    multiprocessing.freeze_support()
    cores = multiprocessing.cpu_count()
    arr1 = np.random.rand(1000000).tolist()
    tmp = time.time()
    pool = multiprocessing.Pool(processes=cores)
    result = pool.map(worker, [arr1], chunksize=1000000/(cores-1))
    print "mp time", time.time()-tmp

我有8个核心。 它通常以仅使用约3%的CPU的7个进程结束约一秒钟,而最后一个进程将永久使用约1/8的CPU ...(已运行约15分钟)。

我知道进程间通信通常会限制并行编程的复杂性,但是通常需要这么长时间吗? 还有什么可能导致最后的过程永远持续下去?

这个线程: Python多处理程序永远不会联接似乎解决了一个类似的问题,但是它不能解决Pool问题。

看来您想将工作分成多个部分。 您可以使用范围功能对数据进行分区。 在Linux上,分叉的进程将获得父内存的写时复制视图,因此您只需传递要处理的索引即可。 在Windows上,没有这种运气。 您需要传递每个子列表。 这个程序应该做

import numpy as np
import multiprocessing
import time
import platform

def worker(a):
    if platform.system() == "Linux":
        # on linux we passed in start:len
        start, length = a
        a = arr1[start:length]
    for i in range(len(a)):
        for j in arr2:
            a[i] = a[i]*j
    return len(a)

arr2 = np.random.rand(10000).tolist()

if __name__ == '__main__':
    multiprocessing.freeze_support()
    cores = multiprocessing.cpu_count()
    arr1 = np.random.rand(1000000).tolist()
    tmp = time.time()
    pool = multiprocessing.Pool(processes=cores)
    chunk = (len(arr1)+cores-1)//cores
    # on Windows, pass the sublist, on linux just the indexes and let the
    # worker split from the view of parent memory space
    if platform.system() == "Linux":
        seq = [(i, i+chunk) for i in range(0, len(arr1), chunk)]
    else:
        seq = [arr1[i:i+chunk] for i in range(0, len(arr1), chunk)]
    result = pool.map(worker, seq, chunksize=1)
    print "mp time", time.time()-tmp

您的观点在这里:

pool.map将自动迭代程序中的[arr1]对象。 请注意,对象是[arr1]而不是arr1 ,这意味着您传递给pool.map的对象的长度仅为1

我认为,最简单的解决办法是更换[arr1]arr1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM