Python 如何并行运行带参数的函数?
感谢下面的代码Python 如何并行运行带参数的函数?,python,python-3.x,Python,Python 3.x,感谢下面的代码 import time from multiprocessing import Process def worker(): time.sleep(2) print("Working") def runInParallel(*fns): proc = [] for fn in fns: p = Process(target=fn) p.start() proc.append(
import time
from multiprocessing import Process
def worker():
time.sleep(2)
print("Working")
def runInParallel(*fns):
proc = []
for fn in fns:
p = Process(target=fn)
p.start()
proc.append(p)
for p in proc:
p.join()
if __name__ == '__main__':
start = time.time()
runInParallel(worker, worker, worker, worker)
print("Total time taken: ", time.time()-start)
但是,如果我将参数添加到worker()
中,它将不再并行运行
import time
from multiprocessing import Process
def worker(ii):
time.sleep(ii)
print("Working")
def runInParallel(*fns):
proc = []
for fn in fns:
p = Process(target=fn)
p.start()
proc.append(p)
for p in proc:
p.join()
if __name__ == '__main__':
start = time.time()
runInParallel(worker(2), worker(2), worker(2), worker(2))
print("Total time taken: ", time.time()-start)
原因可能是什么?这是因为
worker
和worker()之间的差异。第一个是函数,第二个是函数调用。行runInParallel(worker(2)、worker(2)、worker(2)、worker(2)、worker(2))
上发生的情况是,在执行runInParallel
之前,所有四个调用都会运行。如果在并行运行的开头添加一个print(fns)
,您将看到一些不同
快速修复:
def worker_caller():
worker(2)
以及:
这不是很方便,但主要是为了说明问题所在。问题不在函数worker
中。问题是你把传递函数和传递函数调用混淆了。如果您将第一个版本更改为:
runInParallel(worker(), worker(), worker(), worker())
然后你会遇到完全相同的问题
但你可以这样做:
runInParallel(lambda:worker(2), lambda: worker(2), lambda: worker(2), lambda: worker(2))
lambda非常有用。以下是另一个版本:
a = lambda:worker(2)
b = lambda:worker(4)
c = lambda:worker(3)
d = lambda:worker(1)
runInParallel(a, b, c, d)
要传递参数,您需要将它们传递给进程
构造函数:
p = Process(target=fn, args=(arg1,))
您应该修改runInParallel
,以执行可拆分的解包
import time
from multiprocessing import Process
def worker(ii):
time.sleep(ii)
print("Working")
def runInParallel(*fns):
proc = []
for fn in fns:
func, *args = fn
p = Process(target=func, args=args)
p.start()
proc.append(p)
for p in proc:
p.join()
if __name__ == '__main__':
start = time.time()
runInParallel((worker, 2), (worker, 3), (worker, 5), (worker, 2))
print("Total time taken: ", time.time()-start)
流程构造函数接受args和kwargs参数,然后在执行流程时将这些参数传递给流程。
政府对此非常清楚
因此,您的代码应该进行如下修改:
def worker(ii):
time.sleep(ii)
print("Working")
def runInParallel(*fns):
proc = []
for fn in fns:
p = Process(target=fn, args=(2,))
p.start()
proc.append(p)
for p in proc:
p.join()
if __name__ == '__main__':
start = time.time()
runInParallel(worker, worker, worker, worker)
print("Total time taken: ", time.time()-start)
当然,每个进程的参数可能不同,您需要安排将正确的参数传递给args中的每个进程(或者对于关键字参数为kwargs)。
这可以通过传递元组来实现,例如runInParallel((worker,2),(worker,3),(worker,5),(worker,1)
例如,然后在runInParallel
中处理元组,我不知道完整的答案,但您的主要问题是您已将函数引用更改为函数调用,因此您在runInParallel
甚至开始之前调用了工作程序。我认为您需要Process中的另一个参数de>。如何传递不同的参数。例如worker(1)
,worker(5)
,worker(3)
。@blueray更新了答案虽然没有要求提供这种情况,但可能在通用处理函数中,支持任何数量的位置参数都很好,如func,*args=fn;p=Process(target=func,args=args)
def worker(ii):
time.sleep(ii)
print("Working")
def runInParallel(*fns):
proc = []
for fn in fns:
p = Process(target=fn, args=(2,))
p.start()
proc.append(p)
for p in proc:
p.join()
if __name__ == '__main__':
start = time.time()
runInParallel(worker, worker, worker, worker)
print("Total time taken: ", time.time()-start)