gpt4 book ai didi

python - 如果没有 GIL,则不允许来自 Python 的强制转换

转载 作者:行者123 更新时间:2023-12-04 10:08:32 25 4
gpt4 key购买 nike

我正在尝试从这样定义的 C++ 库中调用一个函数:

int somefunc(float timeout);

我在pxd文件中加倍了一个定义:

int somefunc(float timeout) nogil;

但是在对 pyx 文件进行 cythonizing 时,任何使用 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 变量调用此函数的正确方法是什么?

最佳答案

当你查看生成的代码时

timeout = 1.0
Q.somefunc(timeout)

您会看到,timeoutPyObject 并且调用 __pyx_PyFloat_AsFloat 将 is 转换为 cdef-float。然而,在此转换期间可能会引发异常,为此需要 gil - 因此会出现错误消息。

解决方案是在 nogil block 之前强制强制转换为 float:

cdef float timeout = 1.0
with nogil:
Q.somefunc(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. 我们可以在使用实现缓冲区协议(protocol)的对象时释放 GIL,因为缓冲区协议(protocol)(如果正确实现)会锁定缓冲区,并且缓冲区不能从另一个 Python 线程中销毁。其他 Python 对象没有这种内置锁定。

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

关于python - 如果没有 GIL,则不允许来自 Python 的强制转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61452292/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com