对文件进行Cython化并通过导入运行时,会出现错误,提示在获取python解释器状态时存在问题。
删除诸如multiprocessing.start()的多处理代码;切换到Cython自己的prange()。
谷歌搜索错误意味着什么,自从我第一次遇到该错误(2年前)以来,没有一个讨论此问题的结果。
赛顿0.29.6 Python 3.7
使用
构建pyhton3 setup.py build_ext --inplace
setup.py所在的地方
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
ext_modules = [Extension("Logic", ["Logic.pyx"], extra_compile_args=['-Ofast'],)]
setup(name="Logic", ext_modules=cythonize("Logic.pyx"))
还有问题代码...预计会出现一小段错误,但是解释器状态不是其中之一。
import secrets
import os
import time
import Cython
cdef list race = ["Asian", "Black", "White"]
cdef list hair = ["Brown", "Brown", "Brown", "Brown", "Black", "Black", "Black", "Blond", "Blond", "Red"]
cdef list eyes = ["Brown", "Brown", "Brown", "Blue", "Blue", "Blue", "Green", "Green", "Grey", "Hazel"]
cdef list gender = ["Female", "Male", "Female", "Female", "Female", "Female", "Male", "Male", "Male", "Male", "Female", "Female", "Female", "Female", "Male", "Male", "Male", "Male", "Female", "Female", "Female", "Female", "Male", "Male", "Male", "Male", "Female", "Female", "Female", "Female", "Male", "Male", "Male", "Male", "Female", "Female", "Female", "Female", "Male", "Male", "Male", "Male", "Female", "Female", "Female", "Female", "Male", "Male", "Male", "Male", "Female", "Female", "Female", "Female", "Male", "Male", "Male", "Male", "Female", "Female", "Female", "Female", "Male", "Male", "Male", "Male", "Female", "Female", "Female", "Female", "Male", "Male", "Male", "Male", "Female", "Female", "Female", "Female", "Male", "Male", "Male", "Male", "Female", "Female", "Female", "Female", "Male", "Male", "Male", "Male", "Female", "Female", "Female", "Female", "Male", "Male", "Male", "Male", "X", "XXY"]
cdef long age_limit_elder = 115
cdef long weight_limit = 400
cdef long age_limit_adult = 60
cdef long age_limit_child = 18
cdef long weight_limit_infant = 15
cdef long age_limit_infant = 4
cdef long population = 4873057333
cdef long infant = 633497453 # 13%
cdef long child = 1461917200 # 30%
cdef long adult = 2095414652 # 43%
cdef long elder = 682228028 # 14%
cdef list infant_population = []
cdef list child_population = []
cdef list adult_population = []
cdef list elder_population = []
cdef list adult_race_pool = []
cpdef dict adult_generation(long adult=adult, long age_limit_adult=age_limit_adult, long weight_limit=weight_limit, list race=race, list hair=hair, list eyes=eyes, list gender=gender, long age_limit_child=age_limit_child):
cdef long age_ = secrets.choice(range(age_limit_child, age_limit_adult))
cdef long weight_ = secrets.choice(range(90, weight_limit))
cdef str race_ = secrets.choice(race)
cdef str hair_ = secrets.choice(hair)
cdef str eyes_ = secrets.choice(eyes)
cdef str gender_ = secrets.choice(gender)
# adult_population.append({"AGE": age_, "WEIGHT": weight_, "RACE": race_, "HAIR": hair_, "EYES": eyes_, "GENDER": gender_})
return {"AGE": age_, "WEIGHT": weight_, "RACE": race_, "HAIR": hair_, "EYES": eyes_, "GENDER": gender_}
# adult_generation()
# cdef long adult_processes = adult // 4
# adult_processes = 10000
# cdef long adult_processes = 100000
cdef long adult_processes = adult # Fallback
cdef long adult_percent = adult_processes // 10000
cdef double percent = 0
cdef long current = 0
cdef double t1 = time.time()
cdef double master = t1
cdef long i
for i in Cython.parallel.prange(adult_processes, nogil=True):
if current == adult_percent:
percent += 0.01
t2 = time.time()
t3 = t2 - t1
os.system("tput reset")
print(f"{percent}% Complete | {current} Profiles in {t3} Seconds")
current = 0
t1 = time.time()
adult_population.append(adult_generation())
current += 1
cdef long F = 0
cdef long M = 0
cdef long X = 0
cdef long XXY = 0
cdef dict item
for item in adult_population:
if item["GENDER"] == "Female":
F += 1
elif item["GENDER"] == "Male":
M += 1
elif item["GENDER"] == "X":
X += 1
elif item["GENDER"] == "XXY":
XXY += 1
else:
pass
print(f"FEMALE: {F}")
print(f"MALE: {M}")
print(f"X: {X}")
print(f"XXY: {XXY}")
print(f"Total Time: {time.time() - master} Seconds")
结果应该只是一个庞大的伪随机变量列表,就像在Python版本中那样,但在所有线程/内核上都没有奇数的70%CPU限制。
但是,在Cython中,当进行并行或多进程处理时,它在导入时返回“未定义符号:PyInterpreterState_GetID”,并退出。
使用较小的数字进行测试,因为当前数字需要146天的处理时间...更改结果数仍会产生错误。
人们也希望它挂在“ cdef dict项目”上,但是再一次,它甚至都无法解决。
答案 0 :(得分:-2)
我不能说这是一个确定的答案,但是,我注意到Python错误输出非常短。我花了一点时间,然后赌博,将Cython代码直接编译成嵌入式程序包。这个程序包提供了完整的错误输出,即使它一团糟,它仍然可以引导到某个地方。
解释器状态似乎与线程/多处理有关,因此我对该部分进行了调整,并发现错误输出在抱怨GIL。显然,给Python的错误是来自Cython的,但是直到编译为独立的“ C”应用程序时才向用户显示。
此错误似乎集中在GIL周围,输出抱怨它无法从需要GIL的函数中删除GIL,即除返回,收益,打印,简单数学等以外的所有Python代码。 ..
因此,prange及其并行功能对于想要增强纯Python脚本的人来说几乎是无用的。由于任何依赖def,open,threading / multiprocessing模块的东西,或者实际上是任何Pythonic的东西,都会产生此错误,并且如果使用它的那个通过Python导入来测试其Cython代码,则它们只会陷入死胡同,一个google搜索结果中没有出现的行错误。
要解决prange错误,需要重写C中正在与之交互的全部内容,或者导入使用C而不是Python的内容。这再次使它对纯Python开发人员而言不再有用。
最后,我跳到了map函数,该函数允许进行多处理,而不会产生太多进程的开销(最后将达到30亿)。