Python并行处理

时间:2018-09-21 08:36:11

标签: python parallel-processing multiprocessing

我处于以下设置:我有一种方法将目标函数f作为输入。作为该方法的子路由,我想对一小部分点求f。由于f具有很高的复杂度,因此我考虑并行进行。 所有在线示例甚至对于琐碎的功能(例如对5点集进行平方运算)都会挂断电话。他们正在使用多处理库-我不知道我在做什么错。我不确定如何在我的方法中封装该__name__ == "__main__"语句。 (因为它是模块的一部分-我猜我应该使用模块名称而不是"__main__"吗?)

我一直在使用的代码如下

from multiprocessing.pool import Pool
from multiprocessing import cpu_count

x = [1,2,3,4,5]
num_cores = cpu_count()
def f(x):
    return x**2

if __name__ == "__main__":
    pool = Pool(num_cores)
    y = list(pool.map(f, x))
    pool.join()
    print(y)

在spyder中执行此代码时,需要花很长时间才能完成。

所以我的主要问题是:我在这段代码中做错了什么?当此代码是更大方法的一部分时,如何封装__name__语句? 甚至值得将其并行化吗? (一次功能评估可能需要花费几分钟,而串行操作总共需要数小时的时间...)

2 个答案:

答案 0 :(得分:1)

根据documentation

  

close()

Prevents any more tasks from being submitted to the pool. Once all the tasks have been completed the worker processes will exit.
     

terminate()

Stops the worker processes immediately without completing outstanding work. When the pool object is garbage collected
     

terminate()将立即被调用。

     

join()

Wait for the worker processes to exit. One must call close() or terminate() before using join().

所以您应该添加:

from multiprocessing.pool import Pool
from multiprocessing import cpu_count

x = [1,2,3,4,5]

def f(x):
    return x**2

if __name__ == "__main__":
    pool = Pool()
    y = list(pool.map(f, x))
    pool.close()
    pool.join()
    print(y)

您可以不带任何参数调用Pool,默认情况下它将使用cpu_count

  

如果进程为“无”,则使用cpu_count()返回的数字

关于if 名称 ==“ 主要”,请阅读更多信息here

  

因此,您需要考虑只在主程序中执行哪些代码。最明显的例子是您希望创建子进程的代码仅在主程序中运行-因此应使用 name ==' main '

答案 1 :(得分:0)

您可能希望查看所使用的map函数的chunksize参数。

在足够大的输入列表上,您花费了很多时间,只是在与单独的并行进程之间来回传递参数。

此问题的一个症状是,当您使用htop之类的东西时,所有内核都在触发,但<100%。