Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Multiprocessing.Manager()具有全局变量的奇怪行为_Python_Multithreading_Global Variables_Python Multiprocessing - Fatal编程技术网

Python Multiprocessing.Manager()具有全局变量的奇怪行为

Python Multiprocessing.Manager()具有全局变量的奇怪行为,python,multithreading,global-variables,python-multiprocessing,Python,Multithreading,Global Variables,Python Multiprocessing,我对multiprocessing.Manager类有一个问题,当Manager对象是全局变量时,该类的行为非常奇怪 代码1: 导入多处理 从多处理导入管理器 经理=经理() list1=manager.list(范围(4)) dict1=manager.dict({“d”:1,“f”:2}) def process1(列表1,dict1): 打印“进程1” dict1[“3”]=123 列表1.追加(10) def run(): 打印“开始” 全球清单1 全球宣言1 打印“列表1”,列表1 打

我对
multiprocessing.Manager
类有一个问题,当Manager对象是全局变量时,该类的行为非常奇怪

代码1:

导入多处理
从多处理导入管理器
经理=经理()
list1=manager.list(范围(4))
dict1=manager.dict({“d”:1,“f”:2})
def process1(列表1,dict1):
打印“进程1”
dict1[“3”]=123
列表1.追加(10)
def run():
打印“开始”
全球清单1
全球宣言1
打印“列表1”,列表1
打印“dict1”,dict1
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
打印“开始”
j=multiprocessing.Process(target=process1,args=(list1,dict1))
j、 开始()
j、 加入
运行()
输出1:

开始
过程1
开始
清单1[0,1,2,3,10]
dict1{'3':123,'d':1,'f':2}
好的,这意味着全局变量
̀list1
dict1
已被
process1
修改

问题是,当我尝试替换
list1
dict1
时,它不起作用

代码2:

导入多处理
从多处理导入管理器
经理=经理()
list1=manager.list(范围(4))
dict1=manager.dict({“d”:1,“f”:2})
def process1(列表1,dict1):
打印“进程1”
dict1[“3”]=123
list1=manager.list(范围(100104))
def run():
打印“开始”
全球清单1
全球宣言1
打印“列表1”,列表1
打印“dict1”,dict1
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
打印“开始”
j=multiprocessing.Process(target=process1,args=(list1,dict1))
j、 开始()
j、 加入
运行()
输出2:

开始
过程1
开始
清单1[0,1,2,3]
dict1{'3':123,'d':1,'f':2}

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

当一个
管理器.list
对象跨进程共享时,绑定到该对象的名称根本不会共享,即使在所有进程中使用相同的名称也不会共享
global
表示在运行模块的进程中,在整个模块中都可以看到相同的绑定(除非在某些局部范围中被重写);仅仅因为导入了
多处理
,它就神奇地意味着更多;-)

具体来说,主进程中的名称
list1
与辅助进程中的名称
list1
无关。它们之间唯一的关系是,两个名称最初恰好绑定到
Manager.list
的一个共享实例。这通常是你想从他们那里得到的。在这两个过程中,将名称
list1
重新绑定到其他对象不会对名称
list1
在任何其他过程中绑定到的对象产生任何影响

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

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

list1[:] = range(100,104)
相反,不更改任何绑定,而是替换共享的
Manager.list
实例的整个内容(因此主进程也会看到新的列表内容,不是因为名称相同,而是因为两个名称都绑定到同一个对象)

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

短期课程:停止思考名称,而是从对象的角度思考。进程之间永远不会共享名称