python - 是否可以在 nogil 部分使用 Cython 扩展类型?
问题描述
我创建了一个 Cython 扩展类型,我想在 nogil 上下文中使用它。但是编译器总是抛出一个错误。这是我正在尝试做的一个简单示例:
1 # cython: language_level=3
2
3 from cython.parallel import prange
4
5 cdef class C1:
6
7 cdef public:
8 int val
9
10 def __cinit__(self, value):
11 self.val = value
12
13 def iterate_C1():
14
15 cdef int i
16 cdef int N = 4
17 cdef C1 c1_i
18
19 # This compiles fine
20 c1 = C1(4)
21 print(f'c1.val={c1.val}')
22
23 # But this doesn't
24 with nogil:
25 for i in prange(N):
26 c1_i = C1(i)
我得到了一些例外,但它们看起来都是这样的:
Compiling c_one.pyx because it changed.
[1/1] Cythonizing c_one.pyx
Error compiling Cython file:
------------------------------------------------------------
...
print(f'c1.val={c1.val}')
# But this doesn't
with nogil:
for i in prange(N):
c1_i = C1(i)
^
------------------------------------------------------------
c_one.pyx:26:12: Assignment of Python object not allowed without gil
Error compiling Cython file:
------------------------------------------------------------
...
print(f'c1.val={c1.val}')
# But this doesn't
with nogil:
for i in prange(N):
c1_i = C1(i)
^
------------------------------------------------------------
c_one.pyx:26:21: Calling gil-requiring function not allowed without gil
那么是否不可能在 nogil 上下文中使用 Cython 扩展类型?
解决方案
您绝对不能在块cdef
内创建扩展类型的实例。nogil
它们最终是 Python 对象,需要引用计数(包括在一些不明显的地方,例如类型对象)、分配 Python 管理的内存以及释放 的先前内容ci
,包括调用其析构函数。
您应该能够访问它们cdef members
(例如val
对于此类)并调用它们cdef
标记为的函数nogil
。
推荐阅读
- sql - 无法在 Spark SQL 中编写 case 语句
- javascript - 使用javascript查找存在于同一对象数组中的两个值
- django - 在 MultipleChoiceField 中渲染图像
- reactjs - 是否可以在样式组件中使用媒体选择器来设置属性?
- asp.net-core - C# 上传 IList
到一个蔚蓝的斑点 - php - 在此行找到多个注释:- 断点:- 1 行更改- 语法错误
- python - 如何从混乱的 CSV 中提取数据?
- c - 通过 EnumWindows 获取进程 ID...有人可以解释一下为什么这段代码有效吗?
- windows - 无法在 Windows 7x64 上安装 hbase 0.94.13
- r - 整齐的卷窗