Rat*_*Don 12 python class multiprocessing python-multiprocessing
我正在创建一个类的对象(with 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()
Run Code Online (Sandbox Code Playgroud)
但是我收到了一个错误:
TypeError: Pickling an AuthenticationString object is disallowed
for security reasons
Run Code Online (Sandbox Code Playgroud)
为了好奇,我删除了多处理部分,并试着像:
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()
Run Code Online (Sandbox Code Playgroud)
它没有给我任何错误并显示两个对象的地址.
这个错误是什么以及如何让它消失?
KT.*_*KT. 10
这是复制您看到的效果的较短方法:
from multiprocessing import Process
import pickle
p = Process()
pickle.dumps(p._config['authkey'])
Run Code Online (Sandbox Code Playgroud)
TypeError:出于安全原因,不允许对AuthenticationString对象进行腌制
什么是真正发生在这里的是以下内容:process._config['authkey']是秘密密钥,该Process对象被创建上分配。尽管此键只不过是一个字节序列,但是Python使用一个特殊的子类bytes来表示它:AuthenticationString。该子类bytes仅在一个方面与通常的类不同-它拒绝被腌制。
此选择的基本原理如下:authkey用于验证父级和子级流程之间(例如,工作人员与主流程之间)的流程间通信消息,并将其暴露在初始流程族之外的任何地方都可能构成安全风险(因为您原则上可以为工作人员模拟“父进程”,并强制其执行任意代码)。由于酸洗是Python中最常见的数据传输形式,因此禁止酸洗是一种意外暴露authkey的简单方法。
因为您不能腌制一个AuthenticationString,所以您也不能腌制Process该类或其任何子类的实例(因为所有实例都在字段中包含身份验证密钥)。
现在,让我们看一下它们与您的代码之间的关系。您创建一个Manager对象并尝试设置其值dict。该Manager实际上在一个单独的进程中运行,只要你指定的任何数据manager.dict(),Python的需要将这些数据转移到Manager's自己的过程。为了进行这种传输,需要对数据进行腌制。但是,正如我们从前面的段落中知道的那样,您Process无法使对象腌制,因此根本无法使它们共享dict。
简而言之,您可以随意manager.dict()共享任何对象,除了那些不能被腌制的Process对象,例如对象。