Python 多处理中的 Pickle cython class

Pickle cython class in Python Multiprocessing

我有一个在 cython 中实现的 class,它包含我试图与 python 的多处理模块一起使用的 c 指针。 class 将 DLL 文件带到 return class 的一个实例。

我遇到的问题是,虽然实例保留了它们的数据类型,但它们似乎是空的,即我可以访问它们所有的 class 函数,但它们丢失了我之前设置的所有实例值进入。包含 special_class 的代码非常大,所以我无法包含它。

import time
import multiprocessing as mp
from special_module import special_class

def run_task(tasks,nr):
    obj = tasks[nr]['data']
    print obj.get_name()



if __name__ == "__main__":

    m1 = special_class("a.dll")
    m2 = special_class("b.dll")


    tasks = dict()

    tasks[1] = {'data': m1}
    tasks[2] = {'data': m2}


    process1 = mp.Process(target = run_task, name = 'process1', args = (tasks, 1))
    process2 = mp.Process(target = run_task, name = 'process2', args = (tasks, 2))

    process1.start()

    time.sleep(0.2)

    process2.start()

    process1.join()
    process2.join()

上面的脚本给出了输出

None
None

正确的输出应该是

的风格
name.a
name.b

如果我在函数 run_task 中创建实例,它会正常工作,但我正在寻找一种通过在主进程中创建实例来使其工作的方法。这可能吗?

我相信 multiprocessing.Process 腌制了它所有的论点。所以你需要告诉 Python 如何腌制 special_class。您只需要实现方法 special_class.__reduce__ 即可正确腌制数据。

您似乎正在制作 m1m2 两个完整的 special_class 模块 。如果您想让它们成为特定的 class,要么:

from special_class import *

(我推荐)或

m1 = special_class.special_class("a.dll")
m2 = special_class.special_class("b.dll")

None 可能会出现,因为出于某种原因,您输入 m1m2 的方法也接受该模块。我建议尝试 from special_class import * 并解决问题。

多处理库的工作原理是对对象进行酸洗,然后将数据通过管道传输到其他生成的进程。问题是你的 special_class 是不可腌制的。

If I create the instances inside the function run_task it will work fine

这是可行的,因为这样就不需要对对象进行 pickle,从而解决了这个问题。


您需要使 special_class 可腌制。这可以通过多种方式完成。它们都记录在此处:https://docs.python.org/3/library/pickle.html#pickle-inst

基本上有3种机制:

  • 使用自定义 pickler
  • special_class
  • 上实施 __reduce__ 方法
  • special_class 上实施 __getstate____setstate__ 方法(如果您的 class 实例有状态)

我感觉你在 special_class 中引用了一个外部对象。那样的话,参考:https://docs.python.org/3/library/pickle.html#persistence-of-external-objects