如何使用multiprocessing Pool在子进程中修改主进程全局变量
现象解释
你观察到子进程内全局变量修改后后续任务读到更新后的值,是因为Pool(4)会预先创建4个常驻工作进程,同一个工作进程会被复用处理多个任务,修改的是当前进程自身的全局变量副本,并非跨进程共享。主进程与子进程的地址空间完全隔离,所以子进程对普通全局变量的修改不会影响主进程的值。
基于multiprocessing.Value的Pool实现方案
以下代码适配Windows spawn模式,支持多参数传递,可实现子进程修改主进程的共享变量:
from multiprocessing import Pool, Value # 工作进程内的全局变量,用于接收共享变量代理 shared_counter = None # Pool工作进程初始化函数,将主进程创建的共享变量绑定到子进程全局空间 def init_worker(val): global shared_counter shared_counter = val # 并行执行的工作函数,支持传入多个参数 def process_task(add_num, task_id): # 操作共享变量必须加锁,避免竞态条件 with shared_counter.get_lock(): original_val = shared_counter.value print(f"任务{task_id} 初始共享值: {original_val}, 本次追加: {add_num}") shared_counter.value += add_num return f"任务{task_id}执行完成" if __name__ == '__main__': # 主进程创建共享整数变量,'i'代表int类型,初始值为0 global_shared_val = Value('i', 0) # 创建进程池时指定初始化函数,传入共享变量 pool = Pool(processes=4, initializer=init_worker, initargs=(global_shared_val,)) # 多参数任务列表,每个元组对应process_task的一组入参 task_params = [(1, 0), (2, 1), (3, 2), (4, 3)] # 使用starmap自动解包参数元组,无需手动拆包 results = pool.starmap(process_task, task_params) pool.close() pool.join() # 输出最终结果 print(f"所有任务执行完成,主进程共享值最终为: {global_shared_val.value}") print(f"任务返回结果: {results}")
核心要点
- 共享变量的读写操作必须加锁,
Value内置了互斥锁,通过get_lock()获取后配合with语法可自动完成加解锁,避免数据写入异常。 - Windows系统默认使用spawn模式创建进程,必须通过
Pool的initializer参数将共享变量传入子进程,不可直接在主模块全局定义后在子进程调用,否则子进程导入主模块时会重新创建独立的变量,无法和主进程共享。 - 多参数传递可直接使用
starmap方法,会自动将任务列表中的元组解包为函数的入参,无需手动封装/拆包参数。
内容的提问来源于stack exchange,提问作者miran80
相关产品推荐
相关产品推荐

