Python线程与进程中变量修改行为差异的原因咨询
线程与进程的内存模型差异解析:你的代码行为背后的原因
先来看你的原始线程代码(已修正语法格式):
from threading import Thread from multiprocessing import Process def foo(x, y): x += 5 y.append(5) if __name__ == '__main__': x = 0 y = [] thread = Thread(target=foo, args=(x, y,)) thread.start() thread.join() print 'Value of x is: ' + str(x) print 'Value of y is: ' + str(y)
线程运行结果:
Value of x is: 0 Value of y is: [5]
为什么线程中x的+5操作不生效,但y的append操作生效?
这要结合Python的可变/不可变类型特性和线程的内存共享模型来看:
- 关于x:整数
x是Python的不可变类型。当你把x作为参数传入foo函数时,传递的是x当前值的副本。线程里执行x +=5时,并不是修改原来的x对象,而是创建了一个新的整数对象(值为5),这个新对象只存在于foo函数的局部作用域中,和主线程的x没有任何关联。所以主线程的x还是原来的0。 - 关于y:列表
y是Python的可变类型。传递给foo的是这个列表对象的内存引用(相当于指向原对象的“指针”)。由于线程共享同一个进程的内存空间,y.append(5)是直接在原列表对象上进行修改——没有创建新对象,只是给原列表加了元素。所以主线程能看到这个修改后的结果[5]。
当把Thread改为Process后,代码如下:
from threading import Thread from multiprocessing import Process def foo(x, y): x += 5 y.append(5) if __name__ == '__main__': x = 0 y = [] process = Process(target=foo, args=(x, y,)) process.start() process.join() print 'Value of x is: ' + str(x) print 'Value of y is: ' + str(y)
进程运行结果:
Value of x is: 0 Value of y is: []
为什么改用Process后两者均不生效?
进程和线程的核心区别在于内存隔离:每个进程拥有完全独立的内存空间,和父进程的内存是完全分开的。
当你创建Process时,Python会通过序列化(pickle)把参数传递给子进程,子进程拿到的其实是父进程数据的副本——不管是不可变的x还是可变的y,子进程里操作的都是自己内存空间里的拷贝。子进程对这些拷贝的修改,完全不会影响到父进程的原始数据。所以父进程最后输出的还是初始的0和空列表。
如果想让进程间共享数据,你需要使用multiprocessing模块提供的专门工具,比如Value、Array或者Manager,它们会创建跨进程共享的内存区域。
内容的提问来源于stack exchange,提问作者Krisnadi
相关产品推荐
相关产品推荐

