问题描述
res.get()
是阻止多处理的阻塞操作吗?
为什么打印Now the pool is closed and no longer available
5次?
from multiprocessing import Pool,TimeoutError
import time
import os
def f(x):
time.sleep(5)
return x*x
if __name__ == '__main__':
# start 4 worker processes
with Pool(processes=4) as pool:
for i in range(5):
# evaluate "f(20)" asynchronously
res = pool.apply_async(f,(20,)) # runs in *only* one process
print(res.get())
# exiting the 'with'-block has stopped the pool
print("Now the pool is closed and no longer available")
输出:
Now the pool is closed and no longer available
Now the pool is closed and no longer available
Now the pool is closed and no longer available
Now the pool is closed and no longer available
400
400
400
400
400
Now the pool is closed and no longer available
解决方法
在python的multiprocessing
模块中,创建新进程时,它将导入__main__
模块*。基本上,它运行与传递给主线程的文件相同的文件,但是任何if __name__ == '__main__':
块都将失败,因为__name__
将是其他东西。然后,它通过pickle
传递要调用的函数和要调用的参数。
基本上,当您调用with Pool(processes=4) as pool:
时,四个子进程分别启动并执行print语句。
对第二个问题“ res.get()是否是阻止操作”的回答是“是”。您应该将所有工作提交给处理池,以便在等待结果之前开始处理。
移动打印语句并将工作提交与结果检索分开可能看起来像这样:
from multiprocessing import Pool,TimeoutError
import time
import os
def f(x):
time.sleep(5)
return x*x
if __name__ == '__main__':
# start 4 worker processes
with Pool(processes=4) as pool:
future_results = []
for i in range(5):
# evaluate "f(20)" asynchronously
future_results.append(pool.apply_async(f,(20,)))
#get results after submitting all work
for res in future_results:
print(res.get())
#move this inside "if __name__ == '__main__':" so it isn't executed in child processes.
# exiting the 'with'-block has stopped the pool
print("Now the pool is closed and no longer available")
*在Unix上,其功能有所不同。这就是文档中提到的Spawn和Fork之间的区别。