如何解决如何腌制/序列化 swigpyobject?
我正在开发一个与内核模块连接的应用程序。对于这种通信,我在 python 中使用 netlink libnl3.5.0,它使用 swig 将“c”包装到 py 中。问题是当我尝试进行多处理并尝试将 msg 队列共享给不同的进程时。 Python 无法选择/序列化 SwigPyObject 格式的消息。
我试图找到这个对象的高级类实现,但我很困惑。看到其他帖子说要在对象中实现一些 getstate 和 reduce 函数,但我不知道在哪里使用它。
尝试了 dill 包,但我猜 dill 正在使用 pickle 进行底层实现。所以这是返回相同的错误。
以下是我实现的主要部分
def queue_packet(msg,args):
global a
nlh=nl.nlmsg_hdr(msg)
ghdr=genl.genlmsg_hdr(nlh)
if(ghdr.cmd==2):
_,attr=genl.py_genlmsg_parse(nlh,8,None)
a.put(attr)
#print(a.qsize())
return 0
def worker(a):
print("worker started")
while True:
if a.qsize()==0:
continue
attr=a.get()
process_messages_cb(attr)
a.task_done()
return 0
a=multiprocessing.Manager.Queue()
while 1:
nl.nl_recvmsgs(s,rx_cb)
这是接收消息并将消息放入队列的主要部分。不同的工作人员将从队列中获取消息并进一步处理它们。那么如何将消息放入队列以在不同的工作人员/子进程之间共享。 我正在使用这个 https://github.com/thom311/libnl/tree/master/python API。
谢谢
解决方法
要选择一个对象,它需要实现一个 __getstate__
和一个 __setstate__
函数。
我通常做的是以下(在你的接口文件的末尾)。假设对象 MyObject
是您使用 SWIG 包装的对象,但不能为其选择包装器。
#pragma once
class MyOBject {
public:
MyObject() {}
SetA(float a) {m_a = a;}
SetB(float b) {m_b = b;}
private:
float m_a;
float m_b;
};
然后在您的界面文件中,执行以下操作
%extend MyObject {
%pythoncode %{
def __getstate__(self):
args = (a,b)
return args
def __setstate__(self,state)
self.__init__() # construct object
(a,b) = state
self.SetA(a)
self.SetB(b)
%}
}
要使对象成为可拾取对象,您必须能够(以某种方式)从序列化数据中恢复它。在上面的例子中,恢复是通过调用一对函数来完成的。在您的情况下,您需要找到一种方法来序列化对象的状态并从序列化的数据中重新创建它。
这显示了如何制作包装器以使对象变得可拾取,但这需要您更改 libnl 的包装器
另一种选择是将在您实现 __getstate__
和 __setstate__
的 Python 类中传递的 Python 对象包装起来。想法是一样的,您需要能够序列化和恢复对象的状态。我不确定这两种方法中哪一种最简单。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。