使用multiprocessing.map时类变量意外继承前次调用修改值的问题
问题原因解析
核心原因是Python进程池(Pool)的子进程复用机制,和直接创建子进程(Process.start)的行为差异导致:
1. 直接用Process.start()的行为
每次调用Process.start()时,系统会从主进程完整拷贝一份全新的子进程。由于你的主进程中类变量printOne始终保持初始值1,所以每个新创建的子进程都会继承这个初始值,不会出现被修改的情况。
2. 用Pool.map()的行为
进程池在初始化时,会预先创建好固定数量的子进程(默认是CPU核心数),这些子进程会被重复利用,而不是每次调用map都重新创建:
- 第一次调用
map时,进程池里的某个子进程执行doubleSelf方法,把类变量printOne改成了2。执行完任务后,这个子进程不会被销毁,而是放回进程池等待下一次任务。 - 第二次调用
map时,系统会复用这个已经修改过类变量的子进程,所以printOne会保持之前修改后的2。 - 主进程和子进程的内存空间是完全隔离的,子进程里修改类变量不会影响主进程,所以主进程的
printOne始终是1。
补充说明
- Unix/Linux系统下,多进程用的是
fork机制,子进程直接拷贝父进程的内存状态;Windows用的是spawn机制,会重新导入模块创建子进程,但进程池的复用逻辑是一致的——只要子进程没被销毁,它内部的变量状态就会被保留。 - 如果想让每次Pool调用都拿到初始值的类变量,可以在任务方法开头手动重置类变量,或者每次用完进程池后调用
pool.close()+pool.join()销毁进程池,下次重新创建新的进程池。
内容的提问来源于stack exchange,提问作者user23317703
相关产品推荐
相关产品推荐

