如何在Python多进程中修改全局变量?兼顾性能与变量同步
解决Python多进程下修改共享变量并保留性能的问题
我明白你遇到的困境了——多进程能带来不错的性能提升,但全局变量根本改不动;线程能修改全局变量,可CPU密集型任务下性能拉胯。这其实是Python多进程和线程的核心特性导致的,咱们一步步拆解解决:
为什么多进程里的全局变量改不了?
Python的多进程是基于复制内存空间实现的:当你启动子进程时,每个子进程都会复制父进程的所有内存数据(包括result和lock),所以每个进程修改的都是自己专属的result副本,父进程里的原始变量完全不会被影响。而且你定义的mp.Lock也只是父进程的锁,每个子进程都有自己的锁副本,根本起不到跨进程同步的作用。
正确的解决方案:用共享内存变量+跨进程锁
要让多进程能共同修改同一个变量,得用multiprocessing提供的共享内存对象,比如Value或Array,它们存储在所有进程都能访问的共享内存区域里。再配合跨进程锁来保证修改操作的原子性,避免竞态条件。
修改后的多进程代码
import random import threading import multiprocessing as mp import time # 使用共享内存变量替代普通全局变量,'i'表示整数类型 result = mp.Value('i', 0) # 跨进程锁,需要传递给子进程 lock = mp.Lock() def list_append(count, id, out_list, shared_result, shared_lock): # 使用with语句自动管理锁,比手动acquire/release更安全 with shared_lock: shared_result.value += 1 for i in range(count): out_list.append(random.random()) if __name__ == "__main__": start = time.time() size = 10000000 # 要生成的随机数数量 threads = 6 # 进程数 jobs = [] for i in range(threads): out_list = list() # 把共享变量和锁作为参数传给子进程 process = mp.Process( target=list_append, args=(size, i, out_list, result, lock) ) jobs.append(process) # 启动所有进程 for j in jobs: j.start() # 等待所有进程完成 for j in jobs: j.join() print("List processing complete.") end = time.time() print(f"耗时: {end - start:.2f}秒") # 访问共享变量的value属性获取值 print(f"最终result值: {result.value}")
顺便说下线程代码的问题
你线程版本的代码有个关键错误:创建线程时直接调用了list_append(size, i, out_list),这会导致函数在主线程里直接执行,而不是交给子线程运行!正确的写法应该是:
thread = threading.Thread(target=list_append, args=(size, i, out_list))
另外,Python的线程受**GIL(全局解释器锁)**限制,CPU密集型任务(比如你的循环生成随机数)无法真正并行执行,多个线程其实是在同一个CPU核心上交替运行,所以性能远不如多进程。这也是为什么多进程更适合CPU密集型场景的原因。
总结
- 多进程要共享变量:用
mp.Value/mp.Array(适合简单数值/数组)或mp.Manager(适合复杂对象) - 必须配合跨进程锁(
mp.Lock)保证共享变量修改的原子性,避免数据混乱 - 线程适合IO密集型任务,CPU密集型任务优先用多进程
内容的提问来源于stack exchange,提问作者Wesley LB
相关产品推荐
相关产品推荐

