use*_*101 7 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
Run Code Online (Sandbox Code Playgroud)
而且我想sum_nums(1,10**10)
通过将其分解成许多来计算sum_nums(1,1000) + sum_nums(1001,2000) + sum_nums(2001,3000)...
,等等.我知道有一个封闭形式,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?
Run Code Online (Sandbox Code Playgroud)
首先,解决内存问题的最佳方法是使用迭代器/生成器而不是列表:
def sum_nums(low, high):
result = 0
for i in xrange(low, high+1):
result += 1
return result
Run Code Online (Sandbox Code Playgroud)
在 python3 中,range() 生成一个迭代器,因此仅在 python2 中需要它
现在,当您想要将处理拆分到不同的进程或 CPU 核心时,多处理就派上用场了。如果您不需要控制各个工作人员,那么最简单的方法是使用进程池。这将允许您将函数映射到池并获取输出。您也可以apply_async
一次向池中申请一个作业,并获得延迟的结果,您可以通过以下方式获得.get()
:
import multiprocessing
from multiprocessing import Pool
from time import time
def sum_nums(low, high):
result = 0
for i in xrange(low, high+1):
result += i
return result
# map requires a function to handle a single argument
def sn((low,high)):
return sum_nums(low, high)
if __name__ == '__main__':
#t = time()
# takes forever
#print sum_nums(1,10**10)
#print '{} s'.format(time() -t)
p = Pool(4)
n = int(1e8)
r = range(0,10**10+1,n)
results = []
# using apply_async
t = time()
for arg in zip([x+1 for x in r],r[1:]):
results.append(p.apply_async(sum_nums, arg))
# wait for results
print sum(res.get() for res in results)
print '{} s'.format(time() -t)
# using process pool
t = time()
print sum(p.map(sn, zip([x+1 for x in r], r[1:])))
print '{} s'.format(time() -t)
Run Code Online (Sandbox Code Playgroud)
在我的机器上,仅sum_nums
使用 10**10 调用就需要将近 9 分钟,但使用Pool(8)
andn=int(1e8)
将其缩短到一分多钟。
归档时间: |
|
查看次数: |
5307 次 |
最近记录: |