Python多处理队列酸洗错误

Posted

技术标签:

【中文标题】Python多处理队列酸洗错误【英文标题】:Python multiprocessing Queues pickling error 【发布时间】:2021-04-29 18:46:58 【问题描述】:

我有以下课程:

class MDP(object):

    def __init__(self, level, state_var):
        self.state_var = state_var
        self.level = level
        ...
   
    def __repr__(self):
       return "level  var ".format(self.level, self.state_var)

    def __eq__(self, other):
        return self.level == other.level and self.state_var == other.state_var

    def __hash__(self):
        return hash((self.level,) + self.state_var)

    def __lt__(self, other):
        return self.state_var < other.state_var
    ...

我的 GUI 有另一个类,如下所示:

class GUI:
    ...
    self.queue = multiprocessing.Queue()
    self.process = multiprocessing.Process(target=self.start, args=(self.queue,))
    self.process.start()

    def start(self, queue):
        ...
        pygame.init()
        ...
        while self.run:
            clock.tick(Consts.FPS)

            if not queue.empty():
                event = queue.get()

            self.container.render()
            pygame.display.update()

        queue.close()
        pygame.quit()
        sys.exit()
    
    def render_q_values(self, q_values):
        self.queue.put(Event(EventType.QVAL, q_values))

事件很简单,看起来像这样:

class Event():
    def __init__(self, kind, data):
        self.kind = kind
        self.data = data

当我调用gui.render_q_values(q_values) 其中q_values 是一个字典,其中键是MDP 对象和值是整数时,我在event = queue.get() 行收到以下错误:

event = queue.get()

File "/.../python3.6/multiprocessing/queues.py", line 113, in get
    return _ForkingPickler.loads(res)
File ".../mdp.py", line 50, in __eq__
    return self.level == other.level and self.state_var == other.state_var
AttributeError: 'MDP' object has no attribute 'level'

我的 MDP 对象是可散列的,并且所有这些属性都已初始化,我将它们放在集合和字典中,但是当我尝试使用多处理模块将它们放入队列时,我得到了这类错误。主要问题似乎是多处理模块无法腌制我的 MDP 对象,有什么想法吗?

【问题讨论】:

如何初始化 MDP 对象?你能直接腌制和解开那个物体吗?制作minimal reproducible example。我创建了一些 MDP 对象 (m= MDP(1,(1,2,3))) 并通过队列将它们传递给进程,它们进行了很好的比较,并且在每个进程中都有匹配的哈希值。 【参考方案1】:

这个错误实际上与多处理模块无关,而与我在 MDP 对象中定义相等和哈希函数的方式有关:Can't pickle objects with recursive references

【讨论】:

以上是关于Python多处理队列酸洗错误的主要内容,如果未能解决你的问题,请参考以下文章

为啥带有酸洗的多处理序列化取决于范围?

Python 酸洗错误:TypeError:对象泡菜未返回列表。 numpy的问题?

使用 ORTools 实现自定义酸洗代码

使用ORTools实现自定义酸洗代码

悲怆多处理不能腌制

准确确定在 Python 多处理期间腌制的内容