gpt4 book ai didi

python - Multiprocessing.Manager() 全局变量的奇怪行为

转载 作者:行者123 更新时间:2023-12-03 13:10:13 26 4
gpt4 key购买 nike

我对 multiprocessing.Manager 有疑问当管理器对象是全局变量时,该类具有非常奇怪的行为。

代码 1:

import multiprocessing
from multiprocessing import Manager

manager = Manager()

list1 = manager.list(range(4))
dict1 = manager.dict({"d":1,"f":2})

def process1(list1,dict1):
print "process1"
dict1["3"] = 123
list1.append(10)

def run():
print "start"
global list1
global dict1

print "list1",list1
print "dict1",dict1

if __name__ == '__main__':
print "start"
j = multiprocessing.Process(target=process1, args=(list1,dict1))
j.start()
j.join()
run()

输出 1:

start
process1
start
list1 [0, 1, 2, 3, 10]
dict1 {'3': 123, 'd': 1, 'f': 2}

好的,这意味着全局变量 ̀list1dict1已被 process1 修改.

问题是当我尝试替换 list1dict1它不起作用!

代码 2:

import multiprocessing
from multiprocessing import Manager

manager = Manager()

list1 = manager.list(range(4))
dict1 = manager.dict({"d":1,"f":2})

def process1(list1,dict1):
print "process1"
dict1["3"] = 123
list1 = manager.list(range(100,104))

def run():
print "start"
global list1
global dict1

print "list1",list1
print "dict1",dict1

if __name__ == '__main__':
print "start"
j = multiprocessing.Process(target=process1, args=(list1,dict1))
j.start()
j.join()
run()

输出 2:

start
process1
start
list1 [0, 1, 2, 3]
dict1 {'3': 123, 'd': 1, 'f': 2}

知道为什么它返回初始列表 [0, 1, 2, 3]而不是 [100, 101, 102, 103] ?

最佳答案

而一个 Manager.list对象是跨进程共享的,您绑定(bind)到该对象的名称根本不共享 - 即使您在所有进程中使用相同的名称也是如此。 global意味着在运行模块的进程中,整个模块都可以看到相同的绑定(bind)(除非在某些本地范围内被覆盖);它的神奇意义不仅仅在于 multiprocessing被进口了;-)

具体来说,名称 list1在主进程中与名称无关list1在工作进程中。它们唯一的关系是,这两个名称最初都恰好绑定(bind)到 Manager.list 的单个共享实例。 .这通常是你想从他们那里得到的。重新绑定(bind)名称list1到某个其他对象,在任一进程中,对名称 list1 的对象都没有影响必须在任何其他过程中。

因此,在您的第二个示例中,在工作进程中,名称 list1变为(重新)绑定(bind)到新的 manager.list(range(100,104))实例。这对名称 list1 的绑定(bind)没有任何影响。在主要过程中。工作进程也没有任何可能的方法来更改任何其他进程中任何名称的绑定(bind) - 如果发生这种情况,那将是一场噩梦。

不过,您可以更改共享对象的值。但你似乎已经知道了。例如,做

list1[:] = range(100,104)

而是不更改任何绑定(bind),而是替换共享 Manager.list 的全部内容实例(所以主进程也会看到新的列表内容,不是因为名称相同,而是因为两个名称都绑定(bind)到同一个对象)。

顺便说一句,请注意在您的 process1函数, list1无论如何,它甚至不是一个全局名称。它是函数参数之一的名称,因此其作用类似于函数局部变量名称。

短期类(class):停止思考名称,而是从对象的角度思考。名称从不跨进程共享。

关于python - Multiprocessing.Manager() 全局变量的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36933322/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com