如何从Python multiprocessing中获取多进程计算结果?
问题原因
你遇到的问题根源是多进程的内存隔离机制——每个子进程都有独立的内存空间,子进程里给self.s赋值的操作,完全不会影响主进程中对应的MyProcess实例,所以主进程里自然找不到s属性。
下面是几种可行的解决方案:
方案1:使用Queue传递结果
Queue是multiprocessing提供的线程/进程安全的通信队列,子进程可以把计算结果存入队列,主进程从队列中取出。
修改后的代码:
from multiprocessing import Process, Queue class MyProcess(Process): def __init__(self, name, array, result_queue): super(MyProcess, self).__init__() self.name = name self.array = array self.result_queue = result_queue # 传入队列 def run(self): s = 0 for a in self.array: s += a self.result_queue.put((self.name, s)) # 把结果存入队列 if __name__ == '__main__': result_queue = Queue() process_list = [] for i in range(5): p = MyProcess(str(i), [1, 2, 3, 4, 5], result_queue) p.start() process_list.append(p) # 等待所有子进程结束 for p in process_list: p.join() # 从队列中取出所有结果 while not result_queue.empty(): proc_name, total = result_queue.get() print(f"进程{proc_name}的计算结果: {total}")
方案2:使用Pipe传递结果
Pipe是一种双向通信管道,你可以在主进程和子进程之间建立管道,子进程把结果通过管道发回主进程。
代码示例:
from multiprocessing import Process, Pipe class MyProcess(Process): def __init__(self, name, array, conn): super(MyProcess, self).__init__() self.name = name self.array = array self.conn = conn # 传入管道的一端 def run(self): s = 0 for a in self.array: s += a self.conn.send((self.name, s)) # 发送结果 self.conn.close() # 关闭管道 if __name__ == '__main__': process_list = [] connections = [] for i in range(5): parent_conn, child_conn = Pipe() connections.append(parent_conn) p = MyProcess(str(i), [1, 2, 3, 4, 5], child_conn) p.start() process_list.append(p) # 等待子进程结束并收集结果 for p, conn in zip(process_list, connections): p.join() proc_name, total = conn.recv() print(f"进程{proc_name}的计算结果: {total}")
方案3:使用Pool(更简洁的批量处理)
如果只是做这种分块计算的任务,使用multiprocessing.Pool会更简洁,不用手动定义Process子类,直接用map或apply_async就能处理。
代码示例:
from multiprocessing import Pool def calculate_sum(array): s = 0 for a in array: s += a return s if __name__ == '__main__': # 这里可以把大数组分成多个子数组,示例中每个进程处理相同的数组 tasks = [[1,2,3,4,5] for _ in range(5)] with Pool(processes=5) as pool: results = pool.map(calculate_sum, tasks) for idx, total in enumerate(results): print(f"进程{idx}的计算结果: {total}")
方案4:使用Manager创建共享对象
Manager可以创建跨进程共享的字典、列表等对象,子进程可以把结果存入共享对象,主进程直接读取。
代码示例:
from multiprocessing import Process, Manager class MyProcess(Process): def __init__(self, name, array, shared_dict): super(MyProcess, self).__init__() self.name = name self.array = array self.shared_dict = shared_dict # 传入共享字典 def run(self): s = 0 for a in self.array: s += a self.shared_dict[self.name] = s # 把结果存入共享字典 if __name__ == '__main__': with Manager() as manager: shared_dict = manager.dict() # 创建共享字典 process_list = [] for i in range(5): p = MyProcess(str(i), [1, 2, 3, 4, 5], shared_dict) p.start() process_list.append(p) for p in process_list: p.join() # 遍历共享字典获取结果 for proc_name, total in shared_dict.items(): print(f"进程{proc_name}的计算结果: {total}")
内容的提问来源于stack exchange,提问作者yingzi
相关产品推荐
相关产品推荐

