2016-11-28 3 views
4

У меня есть класс, который реализован в cython, содержащий c-указатели, которые я пытаюсь использовать вместе с модулем многопроцессорности python. Класс возвращает DLL-файл для возврата экземпляра класса.Pickle класс cython в Python Multiprocessing

Проблема заключается в том, что, пока экземпляры сохраняют свой тип данных, они кажутся пустыми, то есть я могу получить доступ ко всем их функциям класса, но они потеряли все свои значения экземпляров, которые я установил до их ввода. Код, содержащий 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 он будет работать нормально, но я ищу способ заставить его работать, создав экземпляры в основном процессе. Это возможно?

+0

Попробуйте [с помощью специального пикателя] (https://docs.python.org/3/library/copyreg.html). – Phillip

+0

Каждому окну (ОС) «доступ к классу» требуется зарегистрированная точка на Python. Вы получаете доступ к DLL, но как установить всю процедуру доступа к данным. Нужно использовать 'pythoncom.CoInitialize()'. [check this] (http://stackoverflow.com/questions/26764978/using-win32com-with-multithreading) – dsgdfg

+1

Umm ... 'import special_class', за которым следует' m1 = special_class ("a.dll") 'isn ' юридические; вы не можете вызвать модуль. Я предполагаю, что он немного отличается в реальном коде, но в любом случае важное значение имеет определение класса Cython; вы не можете его пропустить. – ShadowRanger

ответ

0

Многопроцессорная библиотека работает путем травления объектов, а затем передает данные другим нереложенным процессам. Проблема в том, что ваш special_class непригоден.

Если я создаю экземпляры внутри функции run_task он будет работать нормально

Это работает, потому что тогда объект не должен быть маринованный, который работает по этому вопросу.


Вам необходимо сделать свой special_class picklable. Это можно сделать по-разному.Все они задокументированы здесь: https://docs.python.org/3/library/pickle.html#pickle-inst

В основном, есть 3 механизма:

  • Использование пользовательского Pickler
  • Реализовать __reduce__ метод на special_class
  • Реализовать __getstate__ и __setstate__ метод на special_class (если ваш класса)

У меня есть что у вас есть ссылка на внешний объект в вашем special_class. В этом случае обратитесь к: https://docs.python.org/3/library/pickle.html#persistence-of-external-objects

2

Я считаю, что многопроцессорность обрабатывает все свои аргументы. Поэтому вам нужно сказать Python, как рассортировать special_class. Вам просто нужно реализовать метод special_class .__ reduce__, чтобы данные можно правильно травить.

0

Кажется, как будто вы делаете m1 и m2 как полный special_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 * и разобраться.

+0

Нет, 'None' появляется, потому что он не способен рассортировать объект. Если я не использую модуль многопроцессорности, я не получу эту проблему. – Chicony