Как настроить / сериализовать swigpyobject?

#pickle #python-multiprocessing #swig #netlink #dill

#маринованный огурец #python-многопроцессорная обработка #swig #netlink #укроп

Вопрос:

Я работаю над приложением, которое подключается к модулю ядра. для этого сообщения я использую netlink libnl3.5.0 на python, который переносит «c» в py с помощью swig. Проблема заключается в том, когда я пытаюсь выполнить многопроцессорную обработку и пытаюсь разделить очередь сообщений с разными процессами. 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,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.

Спасибо

Ответ №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__ . Идея та же, вам нужно иметь возможность сериализовать и восстановить состояние вашего объекта. Я не уверен, какой из двух подходов является самым простым.

Комментарии:

1. Привет, спасибо за комментарий. Где я должен реализовать этот метод getstate и какие аргументы должны быть переданы. В моем случае libnl — это, по сути, библиотека c. С автоматически сгенерированным swig я могу использовать его с python. Не могли бы вы, пожалуйста, пояснить, где этот метод должен быть реализован? В моем коде python или сгенерированном swig файле «.i»?