Python 3.6.8 - multiprocessing.Pool.apply_async() 不工作
Posted
技术标签:
【中文标题】Python 3.6.8 - multiprocessing.Pool.apply_async() 不工作【英文标题】:Python 3.6.8 - multiprocessing.Pool.apply_async() not working 【发布时间】:2022-01-06 11:23:24 【问题描述】:apply_async 似乎无法正常工作,并且没有任何反应。不知道这里有什么问题。我正在使用 MacOS catalina
import time
from multiprocessing import Pool
def worker(sl):
print(sl)
time.sleep(sl)
return sl
if __name__ == '__main__':
with Pool(processes=3) as pool:
for i in range(5,30,5):
result = pool.apply_async(func=worker,args=(i,))
【问题讨论】:
您使用什么 IDE?并非所有 IDE 都正确处理来自子进程的打印语句。例如 Spyder 刚刚改进了 5.2.0 中的支持,您还覆盖了result
并且只保留最后一个...
我使用 Visual Studio Code 版本:1.61.2
尝试从终端(或 Windows 上的 cmd)运行您的代码
如果你想真正开始使用multiprocessing
(如果你的项目允许的话),我还建议将 python 更新到至少 3.9。自 3.6 以来有几个重要的更新和修复
【参考方案1】:
当您调用pool.apply_async
时,您正在安排要运行的任务。该调用的返回值是一个multiprocessing.pool.AsyncResult
实例,您在该实例上调用get
方法,该实例将阻塞直到任务完成,并将返回apply_async
方法调用中指定的工作函数的返回值。但是您没有在这些AsyncResult
实例中的任何一个上调用get
(或wait
)。相反,你让自己立即掉到with Pool(processes=3) as pool:
块的末尾,这就是你的问题。
文档不是很明确。但是,有以下警告:
警告:
multiprocessing.pool
对象的内部资源需要通过将池用作上下文管理器或手动调用close()
和terminate()
来正确管理(与任何其他资源一样)。不这样做可能会导致进程挂起。
由于with
语句,您正在使用池作为上下文管理器,而实际发生的情况是,在完成with
块时,会调用pool.terminate()
.因此,池中的所有进程在有机会运行您提交的任何任务之前都会立即终止。
由于您对来自worker
的实际返回值不感兴趣,因此保存AsyncResult
对象并对其调用get
的替代方法是在退出@987654340 之前调用pool.close()
后跟pool.join()
@block,会等待所有提交的任务完成:
close()
防止任何更多的任务被提交到池中。完成所有任务后,工作进程将退出。
join()
等待工作进程退出。在使用join()
之前,必须先致电close()
或terminate()
。
import time
from multiprocessing import Pool
def worker(sl):
print(sl)
time.sleep(sl)
return sl
if __name__ == '__main__':
with Pool(processes=3) as pool:
for i in range(5,30,5):
result = pool.apply_async(func=worker,args=(i,))
pool.close()
pool.join()
打印:
5
10
15
20
25
【讨论】:
以上是关于Python 3.6.8 - multiprocessing.Pool.apply_async() 不工作的主要内容,如果未能解决你的问题,请参考以下文章
Python 3.6.8 - multiprocessing.Pool.apply_async() 不工作