【问题标题】:Pickling error when using python multiprocessing with class functions将python多处理与类函数一起使用时出现酸洗错误
【发布时间】:2017-03-30 10:43:24
【问题描述】:

我有三个脚本,scheduler.py,它是基于multiprocessing.Processmultiprocessing.Pipe 的并行任务运行器,第二个脚本是simulation.pyx,它是一个包含一些我想在其中执行的类和函数的脚本通过scheduler.py 并行,最后是一个小的主脚本,我从scheduler.py 创建并行化类的实例,将其传递给simulation.pyx 中的类并运行整个过程。

当目标并行函数位于simulation.pyx 的顶层时,一切正常,但是当我尝试将scheduler.pysimulation.pyx 中的类函数一起使用时,我得到一个酸洗错误。

由于代码有几千行,我只给出一些概念代码:

small_main_script.py:

import simulation
import scheduler


if __name__ == '__main__':

    main = simulation.Main()
    scheduler = scheduler.parallel()
    main.simulate(scheduler)


simulation.pyx:

import scheduler

cdef do_something_with_job(job):
...

cdef class Main:
    cdef public ...
    ...

    def __init__(self):
    ...

    def some_function(self,job):
        ...
        do_something_with_job(job)
        ...

    def simulate(self, scheduler):

        for job in job_list:
            scheduler.add_jobs(job)

        scheduler.target_function = self.some_function

        scheduler.run_in_parallel()

问题是,如果我使用无用的虚拟函数,例如

def sleep(job):
    time.sleep(2)

并将它放在顶层,即在类之外,并行化工作正常,但只要我把它放在类Main 中,我就会得到一个酸洗错误。如果我使用也定义在类Main 中的真实目标函数并且我不想将它移动到顶层,我会得到同样的错误。以下是当我在 Main 类中使用虚拟函数 sleep(self,job) 时发生的情况。当它在课堂外时,它工作正常。

PicklingError: Can't pickle <built-in method sleep of simulation.Main
object at 0x0D4A3C00>: it's not found as __main__.sleep

In [2]: Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Python27\lib\multiprocessing\forking.py", line 381, in main self = load(from_parent)
  File "C:\Python27\lib\pickle.py", line 1384, in load return Unpickler(file).load()
  File "C:\Python27\lib\pickle.py", line 864, in load dispatch[key](self)
  File "C:\Python27\lib\pickle.py", line 886, in load_eof

    raise EOFError
EOFError

我使用的是 Python 2.7

更新

我已设法进一步隔离问题。使用第三方包pathos multiprocessing 时,我可以腌制类函数。现在的问题似乎是在使用作为类实例的函数参数时出现错误。

【问题讨论】:

  • 我是pathos 作者。如果您提供更多详细信息(正如您在上面针对原始酸洗问题所做的那样),也许您更有可能获得进一步的帮助。新的错误是什么样的,代码是什么?
  • “现在的问题似乎是我在使用作为类实例的函数参数时出错” => Python 中的所有内容都是“类实例”,所以问题出在您的特定类上,而不是使用“类实例”。

标签: python python-2.7 multiprocessing python-multiprocessing pathos


【解决方案1】:

来自 Python 多处理 programming guidelines

Picklability:确保代理方法的参数是可picklable。

只有顶级函数是picklable

难以腌制非顶级函数(类/实例方法、嵌套函数等)的原因是很难在子进程中以可移植的方式查找它们。您发送实例方法来执行的进程可能不知道拥有该方法本身的对象。

正如编程指南建议的那样:

但是,通常应该避免使用管道或队列将共享对象发送到其他进程。相反,您应该安排程序,以便需要访问在其他地方创建的共享资源的进程可以从祖先进程继承它。

换句话说,创建一个将方法传递给目标关键字的进程。

Pathos 库扩展了 pickle 协议,允许序列化比标准协议支持的更多类型。

一般来说,不建议混合使用 OOP 和多处理,因为有几种极端情况可能会产生误导。这是其中之一。

【讨论】:

    猜你喜欢
    • 2018-07-26
    • 2021-04-29
    • 1970-01-01
    • 2015-04-07
    • 2017-12-02
    • 2021-06-24
    • 1970-01-01
    • 2019-05-22
    • 2010-12-29
    相关资源
    最近更新 更多