如何在Python中使用多处理并行求和循环
我很难理解如何使用Python的多处理模块 我有一个从如何在Python中使用多处理并行求和循环,python,multiprocessing,Python,Multiprocessing,我很难理解如何使用Python的多处理模块 我有一个从1到n的总和,其中n=10^10,太大,无法放入列表,这似乎是许多使用多处理的在线示例的主旨 是否有办法将范围“拆分”为特定大小的段,然后对每个段执行求和 比如说 def sum_nums(low,high): result = 0 for i in range(low,high+1): result += i return result 我想通过将其分解为许多sum nums(11000)+sum
1
到n
的总和,其中n=10^10
,太大,无法放入列表,这似乎是许多使用多处理的在线示例的主旨
是否有办法将范围“拆分”为特定大小的段,然后对每个段执行求和
比如说
def sum_nums(low,high):
result = 0
for i in range(low,high+1):
result += i
return result
我想通过将其分解为许多sum nums(11000)+sum nums(10012000)+sum nums(20013000)…
来计算sum nums(1,10**10)
。我知道有一种接近形式n(n+1)/2
,但假装我们不知道
这是我试过的
import multiprocessing
def sum_nums(low,high):
result = 0
for i in range(low,high+1):
result += i
return result
if __name__ == "__main__":
n = 1000
procs = 2
sizeSegment = n/procs
jobs = []
for i in range(0, procs):
process = multiprocessing.Process(target=sum_nums, args=(i*sizeSegment+1, (i+1)*sizeSegment))
jobs.append(process)
for j in jobs:
j.start()
for j in jobs:
j.join()
#where is the result?
首先,解决内存问题的最佳方法是使用迭代器/生成器,而不是列表:
def sum_nums(low, high):
result = 0
for i in xrange(low, high+1):
result += 1
return result
在python3中,range()生成一个迭代器,因此这只在python2中需要
现在,当您想要将处理拆分为不同的进程或CPU核心时,就需要进行多处理。如果您不需要控制单个工人,那么最简单的方法就是使用流程池。这将允许您将函数映射到池并获得输出。您也可以使用apply\u async
将作业一次应用到池中,并获得延迟结果,您可以使用.get()
:
在我的机器上,用10**10调用
sum\nums几乎需要9分钟,但是使用Pool(8)
和n=int(1e8)
将这一过程缩短到一分钟多一点。我发现多进程.Pool和map()的使用要简单得多
使用您的代码:
from multiprocessing import Pool
def sum_nums(args):
low = int(args[0])
high = int(args[1])
return sum(range(low,high+1))
if __name__ == "__main__":
n = 1000
procs = 2
sizeSegment = n/procs
# Create size segments list
jobs = []
for i in range(0, procs):
jobs.append((i*sizeSegment+1, (i+1)*sizeSegment))
pool = Pool(procs).map(sum_nums, jobs)
result = sum(pool)
>>> print result
>>> 500500
您可以在根本不进行多处理的情况下进行此求和,并且仅使用生成器可能更简单(如果不是更快的话)
# prepare a generator of generators each at 1000 point intervals
>>> xr = (xrange(1000*i+1,i*1000+1001) for i in xrange(10000000))
>>> list(xr)[:3]
[xrange(1, 1001), xrange(1001, 2001), xrange(2001, 3001)]
# sum, using two map functions
>>> xr = (xrange(1000*i+1,i*1000+1001) for i in xrange(10000000))
>>> sum(map(sum, map(lambda x:x, xr)))
50000000005000000000L
但是,如果您想使用多处理
,也可以这样做。我使用的是多处理分支
,它在序列化方面更好(但在其他方面,并没有真正的不同)
不带多处理功能的版本
速度更快,在我的笔记本电脑上大约需要一分钟。由于产生多个python进程的开销,多处理版本需要几分钟的时间
如果您感兴趣,请点击这里:那么您的问题是如何将一个大列表拆分为N个小列表?
?@JoranBeasley否。我的问题是如何使用多处理来计算多个段上的函数,并将结果相加。我在上面添加了一些代码。请查看中的问题答案-应该会给您一个很好的回答idea@letsc我已经遇到了这个问题,但没有找到我需要的内容您不返回您需要的值,以便将它们输入到某个对象正在侦听的多处理.PIPE
(或其他形式的消息传递(套接字等))这段代码在我的机器上创建了无数的Python副本,我不得不这样做reboot@user4817101这是因为它缺少if\uuuuu name\uuuuu==“\uuuuu main\uuuuuu”:
保护,而您正在Windows上运行。将它添加到池(4)
上面,并相应地缩进所有内容,它至少应该在不损坏您的计算机的情况下运行。@dano我不知道windows的行为是这样的(我正在使用linux)。编辑代码。我迟到了5年,但当我使用一个非常大的n时,这个挂起。有什么线索吗?
# prepare a generator of generators each at 1000 point intervals
>>> xr = (xrange(1000*i+1,i*1000+1001) for i in xrange(10000000))
>>> list(xr)[:3]
[xrange(1, 1001), xrange(1001, 2001), xrange(2001, 3001)]
# sum, using two map functions
>>> xr = (xrange(1000*i+1,i*1000+1001) for i in xrange(10000000))
>>> sum(map(sum, map(lambda x:x, xr)))
50000000005000000000L
>>> xr = (xrange(1000*i+1,i*1000+1001) for i in xrange(10000000))
>>> import pathos
>>> mmap = pathos.multiprocessing.ProcessingPool().map
>>> tmap = pathos.multiprocessing.ThreadingPool().map
>>> sum(tmap(sum, mmap(lambda x:x, xr)))
50000000005000000000L