#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»?