我正在创建一个类的对象(使用 multiprocessing
)并将其添加到 Manager.dict()
以便我可以从字典中删除项目当它的工作完成时在对象内部(项目指向)..
我尝试了以下代码:
from multiprocessing import Manager, Process
class My_class(Process):
def __init__(self):
super(My_class, self).__init__()
print "Object", self, "created."
def run(self):
print "Object", self, "process started."
manager=Manager()
object_dict=manager.dict()
for x in range(2):
object_dict[x]=My_class()
object_dict[x].start()
但是我得到一个错误:
TypeError: Pickling an AuthenticationString object is disallowed
for security reasons
出于好奇,我删除了多处理部分,然后尝试:
from multiprocessing import Manager
class My_class():
def __init__(self):
print "Object", self, "created."
manager=Manager()
object_dict=manager.dict()
for x in range(2):
object_dict[x]=My_class()
它没有给我任何错误并显示了两个对象的地址。
那个错误是什么以及如何让它消失?
最佳答案
这是复制您所看到的效果的一种较短的方法:
from multiprocessing import Process
import pickle
p = Process()
pickle.dumps(p._config['authkey'])
TypeError: Pickling an AuthenticationString object is disallowed for security reasons
这里实际发生的情况如下:process._config['authkey']
是 secret key Process
对象在创建时被分配。虽然这个 key 只不过是一个字节序列,但 Python 使用 bytes
的一个特殊子类来表示它:AuthenticationString
。这个子类与通常的 bytes
只有一个方面不同——它拒绝被 pickle。
此选择背后的基本原理如下:authkey 用于验证父进程和子进程之间(例如,worker 和主进程之间)的进程间通信消息,并将其暴露在初始进程家族之外的任何地方可能会造成安全风险(因为原则上你可以为工作人员模拟一个“父进程”并强制它执行任意代码)。由于 pickling 是 Python 中最常见的数据传输形式,因此禁止它是一种意外暴露 authkey 的简单方法。
由于您不能 pickle AuthenticationString
,您也不能 pickle Process
类或其任何子类的实例(因为它们都在字段中包含身份验证 key ) .
现在让我们来看看它与您的代码有何关联。您创建一个 Manager
对象并尝试设置其 dict
的值。 Manager
实际上在一个单独的进程中运行,每当您将任何数据分配给 manager.dict()
时,Python 都需要将此数据传输到 Manager 的
自己的过程。为了进行这种传输,数据正在被腌制。但是,正如我们从前面的段落中了解到的,您不能 pickle Process
对象,因此根本不能将它们保存在共享的 dict
中。
简而言之,您可以自由使用 manager.dict()
来共享任何对象,但不能被 pickle 的对象除外,例如 Process
对象。
关于Python:TypeError:出于安全原因,不允许 Pickling AuthenticationString 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29007619/