【问题标题】:Pickle cython class in Python MultiprocessingPython多处理中的Pickle cython类
【发布时间】:2017-04-12 01:51:27
【问题描述】:

我有一个在 cython 中实现的类,其中包含我试图与 python 的多处理模块一起使用的 c 指针。该类需要一个 DLL 文件来返回该类的一个实例。

我遇到的问题是,虽然实例保留了它们的数据类型,但它们似乎是空的,即我可以访问它们的所有类函数,但它们丢失了我在进入之前设置的所有实例值。包含 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 中创建实例,它会正常工作,但我正在寻找一种通过在主进程中创建实例来使其工作的方法。这可能吗?

【问题讨论】:

  • 每个 windows(OS) class access 都需要在 Python 上注册一个点。你访问一个DLL但是如何设置所有data access过程。需要使用pythoncom.CoInitialize()。 check this
  • 嗯...import special_class 后跟m1 = special_class("a.dll") 是不合法的;你不能调用一个模块。我认为它在实际代码中略有不同,但无论哪种方式,Cython 类定义在这里都很重要;你不能省略它。

标签: python python-2.7 pickle python-multiprocessing


【解决方案1】:

多处理库的工作原理是腌制对象,然后将数据传送到其他衍生的进程。问题是你的special_class 是不可取的。

如果我在函数 run_task 中创建实例,它将正常工作

这是可行的,因为不需要腌制对象,这可以解决问题。


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

基本上有3种机制:

  • 使用自定义pickler
  • 在special_class 上实现__reduce__ 方法
  • 在special_class 上实现__getstate__ 和__setstate__ 方法(如果您的类实例有状态)

我感觉您在 special_class 中引用了外部对象。这种情况请参考:https://docs.python.org/3/library/pickle.html#persistence-of-external-objects

【讨论】:

    【解决方案2】:

    似乎您正在制作m1 和m2 两者都是完整的special_class 模块。如果你想让它们成为一个特定的class,要么这样做:

    from special_class import *
    

    (我推荐)或

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

    None 的出现可能是因为您输入 m1 和 m2 的方法出于某种原因也接受了该模块。我建议尝试from special_class import * 并解决它。

    【讨论】:

    • 不,None 出现是因为它无法腌制对象。如果我不使用多处理模块,我不会遇到这个问题。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-10
      • 2015-05-29
      • 1970-01-01
      相关资源
      最近更新 更多