[英]Coercion from Python not allowed without the GIL
我正在尝试从定义如下的 C++ 库中调用 function :
int somefunc(float timeout);
我将pxd
文件中的定义加倍:
int somefunc(float timeout) nogil;
但是任何尝试使用 nogil 调用 function 都会在对pyx
文件进行nogil
时导致相同的错误:
timeout = 1.0
with nogil:
Q.somefunc(timeout)
Error compiling Cython file:
------------------------------------------------------------
...
int(block), timeout,
)
timeout = 1.0
with nogil:
Q.somefunc(timeout)
^
------------------------------------------------------------
script.pyx:105:23: Coercion from Python not allowed without the GIL
我还尝试使用 ctype 调用它,这会导致相同的错误。
timeout = ctypes.c_float(1.0)
with nogil:
Q.somefunc(timeout)
仅使用浮点文字有效。 使用实际 Python 变量调用此 function 的正确方法是什么?
当您查看生成的代码时
timeout = 1.0
Q.somefunc(timeout)
你会看到, timeout
是PyObject
并且__pyx_PyFloat_AsFloat
来转换为 cdef-float。 但是,在此转换过程中,可能会引发异常,为此需要 gil - 因此会出现错误消息。
解决方案是强制强制在 nogil-block 之前float
:
cdef float timeout = 1.0
with nogil:
Q.somefunc(timeout)
现在 timeout 已经是 cdef-float 并且 nogil-block 中不需要转换。
有点不相关:我看不到代码和Q
是什么,但大多数时候在让 C/C++ 代码完成工作时释放 gil 是错误的:
当 C/C++ 使用 openMP 进行并行化时,持有/不持有 GIL 不会改变 C/C++ 代码的任何内容(这是一个示例: https://stackoverflow.com/a/60012137/5769463 )。
当线程不持有 GIL 时,其他线程可能会破坏 C/C++ 代码工作所需的对象(如Q
或其他数据)
我们可以在处理实现缓冲区协议的对象时释放 GIL,因为缓冲区协议(正确实现时)会锁定缓冲区,并且缓冲区不能从另一个 Python 线程中销毁。 其他 Python 对象没有这种内置锁定。
但如上所述,它可能不适用于您的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.