Python使用ProcessPoolExecutor返回None及wait不生效问题咨询
问题原因分析
1. 输出None的核心原因
你违反了multiprocessing模块的基础书写规范:if __name__ == "__main__"位置放置错误,且全局执行了print(controller())语句。
Python多进程使用spawn启动模式(Windows、macOS默认模式)时,每个子进程都会重新导入主脚本模块,此时子进程运行环境中__name__的值不是__main__:
- 子进程导入主脚本时,会执行全局的
print(controller()),进入controller函数后,因为if __name__ == "__main__"判断不成立,函数没有触发return逻辑,默认返回None,所以子进程会打印None - 只有主进程的
__name__是__main__,会正常执行完全部逻辑返回列表,打印最终的正确结果
这就是你会先看到None再看到正确列表的原因。
2. wait方法不生效的原因
你在提交任务的循环里直接调用了futuro_i.result():result()方法本身是阻塞方法,调用后会立刻等待当前任务执行完成返回结果,所以你的循环实际上是串行提交执行任务:提交第一个任务后等它2秒跑完,再提交第二个,再等2秒,以此类推。等循环走完所有任务已经全部执行完成了,后面的wait自然看起来没有任何等待效果。
修正后的代码
import time from concurrent.futures import ProcessPoolExecutor, wait, ALL_COMPLETED def threaded_upload(i): time.sleep(2) if i == 0: k = 10 elif i == 2: k = i*i else: k = -99 return [k] def controller(): futures = [] with ProcessPoolExecutor() as pool: for paso in range(4): futuro_i = pool.submit(threaded_upload,paso) futures.append(futuro_i) # 此处wait会真正等待所有任务并发执行完成 wait(futures, return_when=ALL_COMPLETED) merged_list = [] for future in futures: for valor in future.result(): merged_list.append(valor) Lista_Final = merged_list return Lista_Final # 把入口判断移到全局,所有全局执行逻辑都放进这个块里 if __name__ == "__main__": print(controller())
修正后效果
- 不再输出多余的None:子进程导入主脚本时不会进入
if __name__ == "__main__"块,不会执行打印逻辑 - 任务会并行执行,总耗时约2秒而非原来的8秒,
wait方法正常生效
内容的提问来源于stack exchange,提问作者Luis
相关产品推荐
相关产品推荐

