如何使用multiprocessing等并发方式运行函数并修改全局变量
核心问题说明
你当前的代码运行后输出始终是1,原因是multiprocessing.Process创建的子进程拥有独立的内存地址空间,父进程的全局变量会被复制一份到每个子进程内部,子进程对global variable的修改仅作用于自己进程内的副本,既不会同步到主进程,也不会同步到其他子进程,所以主进程最后打印的还是初始值1。
解决方案
分为两种场景适配:
场景1:任务为IO密集型(比如网络请求、文件读写)
直接替换为多线程即可,同进程内的多线程共享全局地址空间,修改全局变量的逻辑和普通函数调用完全一致:
import threading from threading import Thread def runInParallel(*fns): proc = [] for fn in fns: p = Thread(target=fn) p.start() proc.append(p) for p in proc: p.join() variable = 1 def changethevariable(): global variable # 简单逻辑不需要加锁,复杂并发写建议加threading.Lock variable = variable + 1 return variable def changethevariable_again(): global variable variable = variable + 3 return variable runInParallel(changethevariable_again, changethevariable) print(variable) # 输出为5,符合预期
场景2:任务为CPU密集型,必须用多进程做并行
需要使用multiprocessing提供的共享内存对象/Manager容器来同步变量,不能直接使用普通全局变量,修改示例如下:
import multiprocessing from multiprocessing import Process, Value, Lock # 预定义全局占位符,会在子进程初始化时赋值 variable = None lock = None def init(shared_var, shared_lock): global variable global lock variable = shared_var lock = shared_lock def runInParallel(*fns): # 初始化int类型共享变量,初始值为1 shared_var = Value('i', 1) shared_lock = Lock() proc = [] for fn in fns: # 把共享变量和锁通过初始化参数传给子进程 p = Process(target=fn, args=(), initializer=init, initargs=(shared_var, shared_lock)) p.start() proc.append(p) for p in proc: p.join() # 同步共享变量值到主进程普通变量 return shared_var.value def changethevariable(): global variable global lock # 加锁避免竞态条件 with lock: variable.value = variable.value + 1 return variable.value def changethevariable_again(): global variable global lock with lock: variable.value = variable.value + 3 return variable.value variable = runInParallel(changethevariable_again, changethevariable) print(variable) # 输出为5,符合预期
注意事项
- 多线程场景如果存在高频并发写操作,建议加
threading.Lock避免数据异常 - 多进程场景所有对共享变量的写入操作都必须加锁,避免竞态条件导致数据不一致
- 如果需要共享列表、字典等复杂结构,可以使用
multiprocessing.Manager.list()/Manager.dict(),用法和普通Python容器一致
内容的提问来源于stack exchange,提问作者Maximilian Travis
相关产品推荐
相关产品推荐

