Python:TypeError:出于安全原因,不允许选择AuthenticationString对象

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对象,例如对象。