如何在循环上并行运行单个函数?Python 2.7.12
我正在尝试并行化一个程序,它在for循环中使用一个函数,并行地更新一个全局列表/变量。我该如何处理这个问题,以及如何将值传递给函数 示例代码如下所示如何在循环上并行运行单个函数?Python 2.7.12,python,parallel-processing,Python,Parallel Processing,我正在尝试并行化一个程序,它在for循环中使用一个函数,并行地更新一个全局列表/变量。我该如何处理这个问题,以及如何将值传递给函数 示例代码如下所示 #python 2.7.12 import random sum=0 #sample function to take a random integer between 0 to i and add it to global variable sum def hello(i): print "Thread Id :",i #inste
#python 2.7.12
import random
sum=0
#sample function to take a random integer between 0 to i and add it to global variable sum
def hello(i):
print "Thread Id :",i #instead of i it should be the threadID
sum=sum+random.randrange(0,i)
#main function
i=1
for i in range(10):
hello(i) #how to parallelize this function over a loop?
编辑1:
尝试使用多处理中的进程,但不知道如何将值传递给函数以及如何在循环中并行运行
from multiprocessing import Process
sum=0
def Hello():
print 'hello: starting'
sum=sum+i #Don't know how to pass values here
print 'hello: finishing'
if name == 'main':
p1 = Process(target=func1)
p1.start()
p1.join()
print sum
您可以使用multiprocessing.dummy.Pool,它接受后跟参数的函数(见下文) 您还需要担心全局变量的同步问题(有关如何使用Lock的示例,请参见下文) 此外,除非使用“全局和”,否则函数中的和是指局部和变量(全局和示例见下文) threading.current_thread()提供线程id
#python 2.7.12
from multiprocessing.dummy import Pool as ThreadPool
import threading
import random
lock = threading.Lock()
sum = 0
#sample function to take a random integer between 0 to i and add it to global variable sum
def hello(i):
if (i == 0):
return
global sum
print threading.current_thread() #instead of i it should be the threadID
r = random.randrange(0,i)
lock.acquire()
try:
sum = sum + r
finally:
lock.release()
ThreadPool().map(hello, list(range(1, 11)))
print sum
将参数作为元组传递给流程函数的args-kwarg:以下是文档中的示例:
if __name__ == '__main__':
p = Process(target=f, args=('bob',))
p.start()
p.join()
约翰·戈登在评论中所说的也是事实。您需要让主进程(将运行循环)处理求和。基本上,您要做的是一个简单的map/reduce工作
map部分是hello函数,reduce是和。在python中有很多执行map/reduce作业的示例
看看使用管道或共享内存来处理总和,上面提到的多处理文档中详细介绍了这两种方法。全局变量和线程的混合不太好。让
hello()
只返回随机部分,并在主循环中汇总结果,这将是一个更好的设计。@JohnGordon,除了这些是进程,而不是线程。OP:您能发布您尝试过的多处理代码吗?@roganjosh这是我尝试过的代码,来自多处理导入进程sum=0 def func1():print'func1:starting'sum=sum+I#不知道如何在这里传递值print'func1:finishing'if name='main':p1=Process(target=func1)p1.start()p1.join()@ShoebAhmed请编辑问题,以包含您尝试的代码,格式正确。这条评论难以辨认。@roganjosh是stackoverflow的新手,请原谅我的天真。我还将向问题添加代码。这将启动单个进程。文档使用类似的东西(出于未知的原因),但它没有利用多核CPUI的额外功能。CPUI假设您将新流程放在循环中,这将为循环的每个迭代创建一个新流程,并将连接放在循环外。一个更优雅的解决方案是使用pscuderi建议的池,您可以以与您所做的几乎相同的方式启动多个进程,并首先将要处理的数据分块(在由单个分块或for
循环组成的列表中)。将每个进程传递给它自己的唯一块。你的方法确实反映了文档,但我一直不明白它是如何处理GIL的。我以前没有见过多处理.dummy
,所以我需要了解pscuderi的答案。谢谢@pscuderi的帮助。我有一些关于代码的问题,1。在函数hello(i)中,如果i==0,为什么返回?2.你能解释一下函数hello()到底在哪里运行了10次吗?randrange在i==0时引发了一个异常,我假设在这种情况下r只能是0,那么为什么还要麻烦将它添加到sum中呢。map(hello,list(range(10)))调用hello 10次,对于list(range(10))返回的列表中的每个值调用hello一次。