我必须从许多进程中访问一组大型且不可选取的 python 对象。因此,我想确保这些对象没有被完全复制。
根据评论this https://stackoverflow.com/questions/5549190/is-shared-readonly-data-copied-to-different-processes-for-python-multiprocessing and this https://stackoverflow.com/questions/10721915/shared-memory-objects-in-python-multiprocessingpost,对象不会被复制(在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
check.
另一方面,在第三行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
。即使列表在末尾保持不变(如预期),情况也是如此,这意味着列表has被复制。
如何查看对象是否已被复制?