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__ 即可正确腌制数据。
您似乎正在制作 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 *
并解决问题。
多处理库的工作原理是对对象进行酸洗,然后将数据通过管道传输到其他生成的进程。问题是你的 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
我有一个在 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__ 即可正确腌制数据。
您似乎正在制作 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 *
并解决问题。
多处理库的工作原理是对对象进行酸洗,然后将数据通过管道传输到其他生成的进程。问题是你的 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
上实施 - 在
special_class
上实施__getstate__
和__setstate__
方法(如果您的 class 实例有状态)
__reduce__
方法
我感觉你在 special_class
中引用了一个外部对象。那样的话,参考:https://docs.python.org/3/library/pickle.html#persistence-of-external-objects