python 关于multiprocessing中在Namespace的实例下保存dict/list的疑问

livelivelive 2011-12-14 10:36:52
想在多进程中保存一个shared dict,想把这个dict放在了Namespace()实例下,结果发现对其的赋值无效(对list类型的也无效),想不明白是什么原因,是Namespace/NamespaceProxy不支持这种通过实例方法赋值的方式么?希望明白的给讲下是怎么回事,或者有什么办法能实现?谢谢!

原脚本太长,因此通过python shell来show我的疑问所在:

>>> from multiprocessing.managers import SyncManager
>>> mm=SyncManager()
>>> mm.start()
>>> nms=mm.Namespace()
>>> str(nms)
'Namespace()'
>>> nms.nr=0 # 简单的变量没有问题
>>> str(nms)
'Namespace(nr=0)'
>>> nms.nr=55 # 无问题
>>> str(nms)
'Namespace(nr=55)'
>>> nms.d=mm.dict() # shared dict
>>> nms.d
{}
>>> str(nms)
'Namespace(d={}, nr=55)'
>>> nms.d['testkey']=78 # 就是这里,赋值无效,但也不出错
>>> str(nms)
'Namespace(d={}, nr=55)'
>>> d=mm.dict() # 不放在Namespace实例下则正常
>>> d['testkey']=89 # 赋值正常
>>> d['testkey']
89
>>> nms.d=mm.dict(thekey=45) # 用一个kv初始化
>>> str(nms)
"Namespace(d={'thekey': 45}, nr=55)"
>>> nms.d['shit']=66 # 赋值依然无效,也不出错
>>> str(nms)
"Namespace(d={'thekey': 45}, nr=55)"
>>>
...全文
653 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
livelivelive 2011-12-19
  • 打赏
  • 举报
回复
噢,感谢 iambic 解惑,上官网查了下2.7.2文档,原来这段话在我用的2.6.6的文档里面没有,这下明白了,多谢啦~
也多谢 notax 提供例子~
结帖放分~
notax 2011-12-18
  • 打赏
  • 举报
回复
[Quote=引用楼主 livelivelive 的回复:]
想在多进程中保存一个shared dict,想把这个dict放在了Namespace()实例下
[/Quote]



显视不了, 捕上


import multiprocessing

def f(ns):
ns.x *= 10
ns.y *= 10
if 'testkey' in ns.d:
v = ns.d['testkey'] * 10
ns.d = {'testkey': v}

if __name__ == '__main__':
manager = multiprocessing.Manager()
ns = manager.Namespace()
ns.x = 1
ns.y = 2
ns.d = {'testkey': 3}
print 'before', ns
p = multiprocessing.Process(target=f, args=(ns,))
p.start()
p.join()
print 'after', ns


输出
before Namespace(d={'testkey': 3}, x=1, y=2)
after Namespace(d={'testkey': 30}, x=10, y=20)
notax 2011-12-18
  • 打赏
  • 举报
回复
[Quote=引用楼主 livelivelive 的回复:]
nms.d['testkey']=78
[/Quote]
改成
nms.d = {'testkey': 78}




[Quote=引用楼主 livelivelive 的回复:]
想在多进程中保存一个shared dict,想把这个dict放在了Namespace()实例下
[/Quote]


import multiprocessing

def f(ns):
ns.x *= 10
ns.y *= 10
if 'testkey' in ns.d:
v = ns.d['testkey'] * 10
ns.d = {'testkey': v}

if __name__ == '__main__':
manager = multiprocessing.Manager()
ns = manager.Namespace()
ns.x = 1
ns.y = 2
ns.d = {'testkey': 3}

print 'before', ns


before Namespace(d={'testkey': 3}, x=1, y=2)
after Namespace(d={'testkey': 30}, x=10, y=20)


iambic 2011-12-17
  • 打赏
  • 举报
回复
这种重要的行为一般文档里都会写得很清楚。
16.6. multiprocessing — Process-based “threading” interface
16.6.2.7. Managers
Note Modifications to mutable values or items in dict and list proxies will not be propagated through the manager, because the proxy has no way of knowing when its values or items are modified. To modify such an item, you can re-assign the modified object to the container proxy:
livelivelive 2011-12-16
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 userguanguan 的回复:]

貌似Namespace支持基本类型,SyncManager里有list(),dict()方法应该可以满足你的需求.刚才查看了一下API

Namespace()
Create a shared Namespace object and return a proxy for it

dict()
Create a shared dict object and return a pro……
[/Quote]
这个我知道,提问里用的就是SyncManager的dict做的列子,我只是想确定下Namespace下放dict/list之类的是否只能在初始化时赋值,此后都是只读的,谢谢参与~

[Quote=引用 2 楼 omencathay 的回复:]

多进程的环境没有共享变量一说,进程间通信可用管道来操作
[/Quote]
您的说法貌似不确切呀,我接触的perl/python都是有进程间共享变量的,perl不知道是如何实现的,python里面是通过multiprocessing.managers.BaseManager实例化时创建的单独进程提供的,底层貌似是pipe实现的。

谢谢参与的朋友,期待更靠谱的解答~~~
omencathay 2011-12-15
  • 打赏
  • 举报
回复
多进程的环境没有共享变量一说,进程间通信可用管道来操作
livesguan 2011-12-14
  • 打赏
  • 举报
回复
貌似Namespace支持基本类型,SyncManager里有list(),dict()方法应该可以满足你的需求.刚才查看了一下API

Namespace()
Create a shared Namespace object and return a proxy for it

dict()
Create a shared dict object and return a proxy for it.

list()
Create a shared list object and return a proxy for


37,720

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧