分析多进程 Python 脚本时出现神秘的 pickle 错误

Posted

技术标签:

【中文标题】分析多进程 Python 脚本时出现神秘的 pickle 错误【英文标题】:Mysterious pickle error while profiling a multi-process Python script 【发布时间】:2012-07-16 21:00:51 【问题描述】:

我正在使用multiprocessing 模块,我正在使用UpdateMessage 对象(我自己的类),通过multiprocessing.Queue 对象发送,在进程之间进行通信。这是类:

class UpdateMessage:
    def __init__(self, arrayref, rowslice, colslice, newval):
        self.arrayref = arrayref
        self.rowslice = rowslice
        self.colslice = colslice
        self.newval = newval
    def do_update(self):
        if self.arrayref == 'uL':
            arr = uL
        elif self.arrayref == 'uR':
            arr = uR
        else:
            raise Exception('UpdateMessage.arrayref neither uL nor uR')
        arr[self.rowslice, self.colslice] = self.newval

当我运行脚本时,它运行良好。但是,当我使用cProfileprofile 运行它时,会出现以下错误:

_pickle.PicklingError: Can't pickle <class '__main__.UpdateMessage'>: attribute lookup __main__.UpdateMessage failed

它似乎试图腌制课程,但我不明白为什么会发生这种情况。我的代码没有这样做,没有它也可以正常工作,所以它可能是multiprocessing 模块。但是为什么它需要腌制UpdateMessage,我该如何解决这个错误?

编辑:这是发送UpdateMessage 的部分代码(脚本的多个部分执行此操作,但都以相同的方式):

msg = UpdateMessage(uLref, refer[0] + marker[0] - 2,
                    slice(uL.shape[1]), ustar.copy())
queue.put(msg)

回溯不是很有帮助:

Traceback (most recent call last):
  File "/usr/lib/python3.2/multiprocessing/queues.py", line 272, in _feed
    send(obj)

【问题讨论】:

UpdateMessage 被腌制的原因是进程间通信路径只是一个字节流,因此需要将类实例序列化以发送到另一个进程。不过,我不知道为什么 profile 会干扰它。 我遇到了类似的问题:***.com/q/41892297/1878788 这可能与以下错误有关:bugs.python.org/issue9914 【参考方案1】:

我不知道您的流程如何,但是:

'__main__.UpdateMessage'

指的是已启动模块中的UpdateMessage。

当另一个进程不是使用类 UpdateMessage 的模块启动时,UpdateMessage 将不可用。

您必须导入包含 UpdateMessage 的模块,以便 UpdateMessage.__module__ is not '__main__'.

然后Pickle 也可以在其他程序中找到UpdateMessage。

我建议__main__.py 看起来像这样:

import UpdateMessage_module

UpdateMessage_module.main()

【讨论】:

【参考方案2】:

我遇到了同样的问题,并通过在自己的文件中定义要腌制的类来解决它。

【讨论】:

您的建议对我有用,因为这些函数是必须腌制的类的属性。我遇到了_pickle.PicklingError: Can't pickle &lt;function count_annot at 0x7fabb38c3c80&gt;: attribute lookup count_annot on __main__ failed 之类的错误【参考方案3】:

我假设在您的课程被发送到另一个进程之前,您的课程发生了酸洗尝试。最简单的解决方案可能只是在您的类上显式实现 pickle-protocol...

【讨论】:

以上是关于分析多进程 Python 脚本时出现神秘的 pickle 错误的主要内容,如果未能解决你的问题,请参考以下文章

创建链表时出现神秘的分段错误(添加功能)

创建 CloudFront 分配时出现神秘的 CloudFormation 失败

尝试创建 PL/SQL 函数时出现神秘错误

将python代码转换为c ++时出现opencvcornerSubPix异常

尝试运行可执行 Python 脚本时出现致命的 Python 错误

从 shell 脚本运行 python 文件时出现 ModuleNotFoundError 错误