Python多进程遍历循环报错且结果数组为空问题求助
Python multiprocessing多进程问题的分析与修复
原代码与问题
原代码如下:
import multiprocessing as mp from multiprocessing.sharedctypes import Value import time import math resault_a = [] resault_b = [] resault_c = [] def make_calculation_one(numbers): for number in numbers: resault_a.append(math.sqrt(number**3)) def make_calculation_two(numbers): for number in numbers: resault_a.append(math.sqrt(number**4)) def make_calculation_three(numbers): for number in numbers: resault_c.append(math.sqrt(number**5)) number_list = list(range(1000000)) if __name__ == "__main__": mp.set_start_method("fork") p1 = mp.Process(target=make_calculation_one, args=(number_list)) p2 = mp.Process(target=make_calculation_two, args=(number_list)) p3 = mp.Process(target=make_calculation_three, args=(number_list)) start = time.time() p1.start() p2.start() p3.start() end = time.time() print(end - start)
运行后遇到两个问题:
- 结果数组
resault_a、resault_c为空 - 出现报错:
Process Process-1:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/process.py", line 315, in _bootstrap
self.run()
问题分析与修复
1. 结果数组为空的原因与修复
原因:Python多进程中,每个子进程拥有独立的内存空间,主进程的全局列表resault_a、resault_c会被复制到子进程中,子进程对列表的修改仅作用于自身的副本,不会同步到主进程的列表,因此主进程中这些列表始终为空。
修复方案:使用multiprocessing.Manager创建可共享的列表,让子进程直接修改共享内存中的列表,主进程就能获取到计算结果。
2. 报错的原因与修复
原因:
args参数需要传入元组,原代码中args=(number_list)不是元组,括号内单个元素必须加逗号才能被识别为元组,否则会直接将number_list的所有元素作为参数传递,导致子进程函数接收到的参数数量不匹配- 主进程启动子进程后立即结束计时并退出,没有等待子进程执行完成,不仅计时不准确,还可能导致子进程被强制终止
修复方案:
- 将
args=(number_list)修改为args=(number_list,),确保传入的是元组 - 调用
p1.join()、p2.join()、p3.join()等待所有子进程执行完毕后再结束计时
修复后的完整代码
import multiprocessing as mp import time import math def make_calculation_one(numbers, result_list): for number in numbers: result_list.append(math.sqrt(number**3)) def make_calculation_two(numbers, result_list): for number in numbers: result_list.append(math.sqrt(number**4)) def make_calculation_three(numbers, result_list): for number in numbers: result_list.append(math.sqrt(number**5)) number_list = list(range(1000000)) if __name__ == "__main__": mp.set_start_method("fork") # 创建管理器与共享列表 with mp.Manager() as manager: resault_a = manager.list() resault_c = manager.list() p1 = mp.Process(target=make_calculation_one, args=(number_list, resault_a)) p2 = mp.Process(target=make_calculation_two, args=(number_list, resault_a)) p3 = mp.Process(target=make_calculation_three, args=(number_list, resault_c)) start = time.time() p1.start() p2.start() p3.start() # 等待所有子进程完成 p1.join() p2.join() p3.join() end = time.time() print(f"总耗时: {end - start}") print(f"resault_a长度: {len(resault_a)}") print(f"resault_c长度: {len(resault_c)}")
内容的提问来源于stack exchange,提问作者user13719970
相关产品推荐
相关产品推荐

