Python多处理中Pickle-cython类

2024-09-27 02:26:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个用cython实现的类,它包含c指针,我正试图与python的多处理模块一起使用。该类接受DLL文件以返回类的实例。在

我的问题是,虽然实例保留了它们的数据类型,但它们似乎是空的,也就是说,我可以访问它们的所有类函数,但它们丢失了我在它们进入之前设置的所有实例值。包含特殊_类的代码非常大,因此无法包含它。在

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()

上面的脚本给出了输出

^{pr2}$

正确的输出应该是

name.a
name.b

如果我在函数run_任务中创建实例,它会很好地工作,但是我正在寻找一种方法,通过在主进程中创建实例来使它工作。这可能吗?在


Tags: 实例函数runnameimporttaskdatatime
3条回答

多处理库的工作原理是先对对象进行酸洗,然后将数据管道传输到其他派生进程。问题是你的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

基本上有三种机制:

  • 使用定制泡菜器
  • special_class上实现__reduce__方法
  • special_class上实现__getstate____setstate__方法(如果类实例有状态)

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

我相信多处理过程把所有的争论都泡汤了。所以您需要告诉Python如何pickle特殊的_类。您只需要实现方法特殊的_类。uu reduce_uu,这样就可以正确地对数据进行pickle。在

似乎您正在使m1m2都是完整的special_class模块。如果您想让它们成为某个类,请执行以下任一操作:

from special_class import *

(我推荐)或者

^{pr2}$

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

相关问题 更多 >

    热门问题