如何使用池在Python中使用多处理

如何使用池在Python中使用多处理,python,multiprocessing,Python,Multiprocessing,我正在尝试加快一些进程,并尝试为Python脚本使用多个内核。在我将框架应用到我正在做的事情之前,我一直在尝试将其放下。到目前为止,我有一些有效的方法,但它有两个缺点: 1它从每次迭代中输出信息-我只需要最终值 2它只比我测试时的原始时间加快了60%,这更好,但不是游戏规则的改变者 代码: import multiprocessing as mp import time import itertools start = time.clock() processes = [] output_lis

我正在尝试加快一些进程,并尝试为Python脚本使用多个内核。在我将框架应用到我正在做的事情之前,我一直在尝试将其放下。到目前为止,我有一些有效的方法,但它有两个缺点: 1它从每次迭代中输出信息-我只需要最终值 2它只比我测试时的原始时间加快了60%,这更好,但不是游戏规则的改变者

代码:

import multiprocessing as mp
import time
import itertools
start = time.clock()
processes = []
output_list = [] 

def all_combinations(count_arg):
    returns_list = []
    for i in range(1,count_arg+1):
        tmp_comb = list(itertools.combinations(range(0,count_arg),i))
        for tmp_tup in tmp_comb:
            returns_list.append(tmp_tup)
    return returns_list
def worker(num):   
    tmp_output = len(all_combinations(num))
    return tmp_output
if __name__ =='__main__':
    pool = mp.Pool(8)
    num_list = range(24)
    output_list2 = pool.map(worker, num_list)   
    pool.close()
    pool.join       
elapsed = (time.clock() - start)
results = output_list
print elapsed
这就是我使用的非多重处理案例:

import time
import itertools
start = time.clock()
processes = []
def all_combinations(count_arg):
    returns_list = []
    for i in range(1,count_arg+1):
        tmp_comb = list(itertools.combinations(range(0,count_arg),i))
        for tmp_tup in tmp_comb:
            returns_list.append(tmp_tup)
    return returns_list

def worker(num,output):
    """thread worker function"""
    tmp_output = len(all_combinations(num))
    return tmp_output

for i in range(24):
    processes.append(worker(i,"hi"))

elapsed = (time.clock() - start)

print len(processes)
print elapsed

你正在生成很多列表,只是为了把它们扔掉。。。我会将所有_组合更改为一个生成器:

def all_combinations(count_arg):
    for i in range(1,count_arg+1):  # xrange on python2.x
        # yield from itertools.combinations(...) on python3.3+
        for comb in itertools.combinations(range(0,count_arg),i)):
            yield comb
现在worker需要更改以从生成器中获取项目数,而不是列表

def worker(num):
    return sum(1 for _ in all_combinations(num))
这些变化大多只是美学上的——你可能不会注意到这样或那样的大幅加速,尽管我可能是错的,就像任何事情一样,你永远都不会知道,直到你描述

现在,这已经不重要了,关于你真正的问题

1它从每次迭代中输出信息

当然,multiprocessing.Pool.map将为池中的每个进程提供一个结果。在这种情况下,每个num_列表将得到24个。幸运的是,这个过程的reduce阶段非常简单-因为worker返回的每个元素都只是部分和,所以您可以只获得输出列表的和:

print sum(output_list2)
2它只会让事情加速一点点


这是因为您的算法不能很好地扩展。你的速度只能和你运行最慢的工人一样快——而且你的工人并不是都在相同的时间执行任务。请注意,随着数字越来越高,在给定的worker中,您正在进行越来越多的组合。这使得使用较高数字(如24)的工人比使用较低数字(如12)的工人计算成本更高。要获得更好的加速,您需要更好的负载平衡。

奇怪的错误-我试图修复代码块的缺失,但代码块无法正常工作。想法?这是因为一系列的缺点1,2.等等,@user3467349-markdown或者just-SO的变体在处理紧跟无序或有序列表的代码时有一些奇怪的行为。诀窍是在列表和代码块之间插入一些有意义的垃圾。对于格式问题,我正在尝试修复它…您只需要在列表末尾添加一个空行。感谢您对设置进行了一些改进,并解决了原始问题。我实际上想要时间的总和,所以在if语句中定义和打印就解决了这个问题。