繁体   English   中英

没有 GIL 就不允许来自 Python 的强制

[英]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)

你会看到, timeoutPyObject并且__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 是错误的:

  1. 当 C/C++ 使用 openMP 进行并行化时,持有/不持有 GIL 不会改变 C/C++ 代码的任何内容(这是一个示例: https://stackoverflow.com/a/60012137/5769463 )。

  2. 当线程不持有 GIL 时,其他线程可能会破坏 C/C++ 代码工作所需的对象(如Q或其他数据)

  3. 我们可以在处理实现缓冲区协议的对象时释放 GIL,因为缓冲区协议(正确实现时)会锁定缓冲区,并且缓冲区不能从另一个 Python 线程中销毁。 其他 Python 对象没有这种内置锁定。

但如上所述,它可能不适用于您的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM