Python 3.x manager.dict中的python multiprocessing manager.list

Python 3.x manager.dict中的python multiprocessing manager.list,python-3.x,multiprocessing,Python 3.x,Multiprocessing,下面是python代码: from multiprocessing import Manager manager = Manager() globals = manager.dict() globals["queue"] = manager.Queue() #following line fails globals["queue"].put("Starting") 失败并出现错误: File "<string>", line 2, in __getitem__ File

下面是python代码:

from multiprocessing import Manager

manager = Manager()
globals = manager.dict()
globals["queue"] = manager.Queue()

#following line fails
globals["queue"].put("Starting")
失败并出现错误:

  File "<string>", line 2, in __getitem__
  File "/usr/lib/python3.5/multiprocessing/managers.py", line 732, in _callmethod
    raise convert_to_error(kind, result)
multiprocessing.managers.RemoteError: 
---------------------------------------------------------------------------
Unserializable message: ('#RETURN', <queue.Queue object at 0x7feb68a68ef0>)
---------------------------------------------------------------------------
文件“”,第2行,在__
文件“/usr/lib/python3.5/multiprocessing/managers.py”,第732行,在调用方法中
引发转换为错误(种类、结果)
multiprocessing.managers.RemoteError:
---------------------------------------------------------------------------
不可序列化消息:(“#RETURN”,)
---------------------------------------------------------------------------

有人能解释一下原因吗?

简而言之,您试图存储不可序列化队列(它本身是线程安全的),这是在滥用线程安全dict。最好的方法是使用自变量来存储使用
manager
创建的集合:

d = manager.dict()
q = manager.Queue()
然后
q.put(“启动”)
工作。您需要将其直接传递给将在单独流程中执行的函数或方法,例如:

def f(d,q):
    d['a'] = 1
    q.put('a')

p = Process(target=f, args=(d,q,))
multiprocessing.manager
被认为是线程安全集合的提供者,线程和进程可以重用这些集合。需要注意的是,源于
管理器的对象不能保存使用它创建的其他对象


我推荐一本非常友好的书,其中有很多好的例子可供阅读。

谢谢@sophros问题是我想把很多变量传递给一个进程,我不想有一个巨大的方法签名。我认为更优雅的方法是将所有共享状态打包成一个全局dict,然后将其传递给子进程。回顾过去,python抱怨这一点是有道理的,因为管理器队列附带了大量逻辑/代码,因此它不是一个可以序列化并发送到不同进程(甚至可能在不同的机器上)的简单对象。即使是非常复杂的对象也可以在python中序列化。不可序列化的引用包含无法保证在取消勾选时不会更改的内容(例如,对文件、互斥、网络/数据库连接等的引用)。在这种情况下,不能pickle(这样做没有意义)的是互斥、信号量或对进程的引用(将在实现中验证)。