Python 中 multiprocessing 模块的并行编程用例

0 投票
1 回答
803 浏览
提问于 2025-04-18 18:16

我对Python还是个新手,正在尝试使用Python的多进程模块来写快速的代码。其实我想问的问题很简单:我想了解多进程的不同用法,但我有点困惑,因为我不太确定这些代码是怎么工作的,所以很难做出正确的总结。

import numpy as np
from multiprocessing import Process, Pool

def sqd(x):
  return x*x.T

A = np.random.random((10000, 10000))

if __name__ == '__main__':
   pool = Pool(processes = 4)
   result = pool.apply_async(sqd, [A])
   print result.get(timeout = 1)
   print len(pool.map(sqd, A))

不过,当我尝试进行一些总结,以加速随机矩阵的生成时,结果并不太理想。

import numpy as np
from multiprocessing import Pool

def sqd(d):
  x = np.random.random((d, d))
  return x*x.T

D=100

if __name__ == '__main__':
   pool = Pool(processes = 4)
   result = pool.apply_async(sqd, [D])
   print result.get(timeout = 1)
   print pool.map(sqd, D)

所以输出结果是:

$ python prueba2.py
[[ 0.50770071  0.36508745  0.02447127 ...,  0.12122494  0.72641019
0.68209404]
[ 0.19470934  0.89260293  0.58143287 ...,  0.25042778  0.05046485
0.50856362]
[ 0.67367326  0.76929582  0.4232229  ...,  0.72910757  0.56047056
0.11873254]
..., 
[ 0.91234565  0.20216969  0.2961842  ...,  0.57539533  0.99836323
0.79875158]
[ 0.85407066  0.99905665  0.12948157 ...,  0.58411818  0.06688349
0.71026483]
[ 0.0599241   0.82759421  0.9532148  ...,  0.22463593  0.0859876
0.41072156]]
Traceback (most recent call last):
File "prueba2.py", line 14, in <module>
print pool.map(sqd, D)
File "/home/nacho/anaconda/lib/python2.7/multiprocessing/pool.py", line 251, in map
return self.map_async(func, iterable, chunksize).get()
File "/home/nacho/anaconda/lib/python2.7/multiprocessing/pool.py", line 304, in   map_async
iterable = list(iterable)
TypeError: 'int' object is not iterable

在这种情况下,我知道我给“某个东西”传递了错误的参数,但我不太清楚原因是什么。我想知道在这种特定情况下,以及其他情况下,如何正确地将列表或范围传递给多进程模块。此外,我还想了解如何在执行后释放内存,因为我之前运行时没有出现内存错误……

我想补充一些细节,除了想知道多进程的不同用例外,我问这个问题的动机是因为我拍了一张我的处理器在工作时的照片,发现有一个孤立的进程只在单个处理器上运行,我猜是因为random()的原因,所以我想把整个任务并行化。

希望我没有说得太模糊。谢谢!

1 个回答

2

你不能在想要用 multiprocessing 计算的函数内部定义参数。pool.map 的作用是把你的 A 数组分成小块,然后在不同的处理器之间进行处理,直到所有的任务完成。不过在你的代码中,你只是把输入数组的维度作为参数传给了 pool.map,所以它只计算了一次就出错了。其实 map 需要的是你的函数和一个可迭代的参数,也就是可以循环处理的东西。

撰写回答