Manager代理对象无法传播对容器内(非托管)可变对象所做的更改。因此,换句话说,如果您有一个
manager.list()对象,则对托管列表本身的任何更改都将传播到所有其他进程。但是,如果你有一个正常的Python列表
内 该列表,在列表内的任何变化都不会传播的,因为经理没有检测变化的方式。
为了传播的变化,你必须使用
manager.list()的嵌套列表对象太(需要的Python
3.6或更新版本),或需要修改的
manager.list()直接对象(见注释上
manager.list的Python
3.5或以上)。
例如,考虑以下代码及其输出:
import multiprocessingimport timedef f(ns, ls, di): ns.x += 1 ns.y[0] += 1 ns_z = ns.z ns_z[0] += 1 ns.z = ns_z ls[0] += 1 ls[1][0] += 1 # unmanaged, not assigned back ls_2 = ls[2] # unmanaged... ls_2[0] += 1 ls[2] = ls_2 # ... but assigned back ls[3][0] += 1 # managed, direct manipulation di[0] += 1 di[1][0] += 1 # unmanaged, not assigned back di_2 = di[2] # unmanaged... di_2[0] += 1 di[2] = di_2 # ... but assigned back di[3][0] += 1 # managed, direct manipulationif __name__ == '__main__': manager = multiprocessing.Manager() ns = manager.Namespace() ns.x = 1 ns.y = [1] ns.z = [1] ls = manager.list([1, [1], [1], manager.list([1])]) di = manager.dict({0: 1, 1: [1], 2: [1], 3: manager.list([1])}) print('before', ns, ls, ls[2], di, di[2], sep='n') p = multiprocessing.Process(target=f, args=(ns, ls, di)) p.start() p.join() print('after', ns, ls, ls[2], di, di[2], sep='n')输出:
beforeNamespace(x=1, y=[1], z=[1])[1, [1], [1], <ListProxy object, typeid 'list' at 0x10b8c4630>][1]{0: 1, 1: [1], 2: [1], 3: <ListProxy object, typeid 'list' at 0x10b8c4978>}[1]afterNamespace(x=2, y=[1], z=[2])[2, [1], [2], <ListProxy object, typeid 'list' at 0x10b8c4630>][2]{0: 2, 1: [1], 2: [2], 3: <ListProxy object, typeid 'list' at 0x10b8c4978>}[2]如您所见,将新值直接分配给托管容器时,它会发生变化。当将其分配给托管容器中的可变容器时,它不会更改;但是,如果然后 将 可变容器 重新分配
给托管容器,它将再次更改。使用嵌套的托管容器也可以,直接检测更改而不必分配回父容器。



