Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
没有GIL,不允许来自Python的强制 我试图从这样定义的C++库调用函数: int somefunc(float timeout);_Python_Cython_Gil - Fatal编程技术网

没有GIL,不允许来自Python的强制 我试图从这样定义的C++库调用函数: int somefunc(float timeout);

没有GIL,不允许来自Python的强制 我试图从这样定义的C++库调用函数: int somefunc(float timeout);,python,cython,gil,Python,Cython,Gil,我在pxd文件中加倍了定义: int somefunc(float timeout) nogil; timeout = 1.0 with nogil: Q.somefunc(timeout) 但是,在对pyx文件进行Cythonization操作时,任何使用nogil调用函数的尝试都会导致相同的错误: int somefunc(float timeout) nogil; timeout = 1.0 with nogil: Q.somefunc(timeout)

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

int somefunc(float timeout) nogil;
 timeout = 1.0
 with nogil:
     Q.somefunc(timeout)
但是,在对
pyx
文件进行Cythonization操作时,任何使用
nogil
调用函数的尝试都会导致相同的错误:

int somefunc(float timeout) nogil;
 timeout = 1.0
 with nogil:
     Q.somefunc(timeout)
我还尝试使用ctype调用它,这会导致相同的错误

timeout = ctypes.c_float(1.0)
with nogil:
    Q.somefunc(timeout)

只有使用浮点文本才有效。使用实际的Python变量调用此函数的正确方法是什么?

当您查看生成的

timeout = 1.0
Q.somefunc(timeout)
您将看到,
timeout
PyObject
,调用
\uuupyx\upyfloat\uasfloat
将is转换为cdef float。但是,在此转换过程中,可能会引发异常,因此需要gil,因此会显示错误消息

解决方案是在nogil块之前强制执行
float

cdef float timeout = 1.0
with nogil:
    Q.somefunc(timeout)
现在超时已经是cdef float,nogil块中不需要转换


稍微无关:我看不到代码和
Q
是什么,但大多数情况下,在让C/C++代码完成工作时释放gil是错误的:

  • 当C/C++使用openMP进行并行化时,保持/不保持GIL不会改变C/C++代码的任何内容(下面是一个示例:)

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

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


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

    是的,
    cdef
    确实有效。谢谢你的解释,这很有道理。我非常感谢关于是否解锁GIL的进一步讨论。在我的例子中,C++可以等待IO,不使用任何Python对象,只使用原始内存缓冲区。因此,我认为在这种情况下解锁GIL是合理的。