【问题标题】:How to pickle/ serialize a swigpyobject?如何腌制/序列化 swigpyobject?
【发布时间】:2021-01-28 17:39:20
【问题描述】:

我正在开发一个与内核模块连接的应用程序。对于这种通信,我在 python 中使用 netlink libnl3.5.0,它使用 swig 将“c”包装到 py 中。问题是当我尝试进行多处理并尝试将 msg 队列共享给不同的进程时。 Python 无法腌制/序列化 SwigPyObject 格式的消息。

我试图找到这个对象的高级类实现,但我很困惑。看到其他帖子说要在对象中实现一些 getstatereduce 函数,但我不明白在哪里使用它。

尝试过 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,0,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。

谢谢

【问题讨论】:

    标签: pickle python-multiprocessing swig netlink dill


    【解决方案1】:

    对于一个可拾取的对象,它需要实现一个__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 的包装器

    另一种选择是将传递的 python 对象包装在一个 python 类中,您为此实现了__getstate____setstate__。想法是一样的,你需要能够序列化和恢复你的对象的状态。我不确定这两种方法中哪一种最简单。

    【讨论】:

    • 您好,感谢您的评论。我应该在哪里实现这个 getstate 方法以及应该传递什么参数。就我而言,libnl 基本上是一个 c lib。使用自动生成的 swig,我可以将它与 python 一起使用。您能否详细说明应该在哪里实施这种方法?在我的 python 代码或 swig 生成的“.i”文件中?
    猜你喜欢
    • 1970-01-01
    • 2021-01-27
    • 2018-12-10
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多