我必须从许多进程访问一组较大且不可选择的python对象。因此,我想确保这些对象不被完全复制。在Linux系统上检查python多处理中的fork行为
根据在this和this后的注释,对象不会被复制(在unix系统上),除非它们被更改。但是,引用一个对象将改变其引用计数,然后将被复制。
到目前为止这是否正确?由于我的关注是由于我的大型对象的大小,我没有问题,如果这些对象的小部分被复制。
为了确保我理解正确的一切,没有什么意外的话,我实现了一个小的测试程序:
from multiprocessing import Pool
def f(arg):
print(l, id(l), object.__repr__(l))
l[arg] = -1
print(l, id(l), object.__repr__(l))
def test(n):
global l
l = list(range(n))
with Pool() as pool:
pool.map(f, range(n))
print(l, id(l), object.__repr__(l))
if __name__ == '__main__':
test(5)
在f
第一线,我希望id(l)
在所有函数返回相同的数来电,因为在id
检查前列表没有被更改。
另一方面,在f
的第三行中,id(l)
应在每个方法调用中返回不同的数字,因为列表在第二行中更改。
但是,程序输出令我困惑。
[0, 1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[-1, 1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, -1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, -1, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, -1, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, 3, 4] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, 3, -1] 139778408436488 <list object at 0x7f20b261d308>
[0, 1, 2, 3, 4] 139778408436488
id是在所有通话和f
线相同。即使列表在最后保持不变(如预期),情况也是如此,这意味着列表已经被复制了。
如何查看对象是否已被复制?
一旦对象被创建没有任何东西可以改变它的ID。 –
@RossRidge:当我复制对象,岂不是在比原来的内存不同的地方?有没有办法获得这个内存地址(如果'ID'返回别的东西)? – Samufi
谢谢,@JonathanEunice。我试图纠正我的陈述。现在好吗? – Samufi