У меня есть библиотека объектов, скомпилированная с использованием Cython. Когда я пытаюсь использовать эти объекты в простом сценарии, используя python 3 с мультипроцессором (Пул) python выдает ошибку засоления. Странная вещь в том, что если я использую python 2, everithing работает как положено (компилирует код с помощью Cython в python 2 и запускает его с python 2). Более того, когда я пытаюсь выполнить простой сценарий для выбора объектов Cython на python 3 (без многопроцессорной обработки), проблем не возникает.
Вот небольшой пример того, что у меня есть:
example_lib.pyx:
'''
example_lib.pyx
'''
#import numpy as np
include "cython_object.pyx"
cython_object.pyx:
cdef class CythonObject:
def __init__(self, str name, int a, int b):
self._name = name
self._a = a
self._b = b
property Name:
'''
Returns the name of the object.
'''
def __get__(self):
return self._name
property A:
'''
Returns a.
'''
def __get__(self):
return self._a
property B:
'''
Returns b.
'''
def __get__(self):
return self._b
cpdef getSum(self):
return self._a + self._b
cpdef dict pack(self):
cdef dict pack = { 'name': self._name
, 'a' : self._a
, 'b' : self._b
}
return pack
cpdef unPack(self, dict pack):
self._name = str(pack['name'])
self._a = int(pack['a'])
self._b = int(pack['b'])
example_lib_setup:
try:
from setuptools import setup
from setuptools import Extension
except ImportError:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
import numpy
setup(
name = 'cythonobjects'
,ext_modules = cythonize("example_lib.pyx")
,include_dirs=[numpy.get_include()]
)
test.py:
import multiprocessing
from example_lib import *
def runReplica(inputs):
(i, objs) = inputs
for obj,pack in objs:
obj.unPack(pack)
print('Rep:{}. Name: {}. {} + {} = {}'.format(i, obj.Name, obj.A, obj.B, obj.getSum()))
if __name__ == '__main__':
obj1 = CythonObject('obj1', 2, 3)
obj2 = CythonObject('obj2', 4, 2)
objs = [obj1, obj2]
num_rep = 3
num_pool = 2
packs = [(obj,obj.pack()) for obj in objs]
if num_pool==1 or num_rep==1:
for i in range(num_rep):
runReplica((i,packs))
else:
pool = multiprocessing.Pool(num_pool)
print ("Running parallelized replicas")
pool.map(runReplica,[(i,packs) for i in range(num_rep)])
Makefile:
PYTHON=py -3
PYTHONVERSION=36
PYTHONHOME=C:\Python36
NUMPYINCLUDE=C:\Python36\lib\site-packages\numpy\core\include
CYTHON=cython.exe
CC=gcc
RM=rm
RMR= rm -r
MKDIR=mkdir
MKDIRR=mkdir -r
RMDIR=rmdir /s /q
CP=cp
UIC= pyside-uic
RCC= pyside-rcc
DEV=0
DEBUG=0
all:
make example_pyd
example_pyd:
$(PYTHON) example_lib_setup.py build_ext --inplace
-$(RM) example_lib.c
test:
$(PYTHON) test.py
clean:
ifeq ($(PYTHONVERSION),27)
$(RM) example_lib.pyd
endif
ifeq ($(PYTHONVERSION),36)
$(RM) example_lib.cp36-win_amd64.pyd
endif
-$(RMR) build
Они были протестированы на платформе windows 10 с использованием Python 3.6.7, cython 0.25.2 , Python 2.7.14 и та же версия Cython (для py2).
Для компиляции с python 2 измените значения связанных переменных в Makefile.
Заранее спасибо ,