简体   繁体   English

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

[英]Coercion from Python not allowed without the GIL

I am trying to call a function from a C++ library defined like this:我正在尝试从定义如下的 C++ 库中调用 function :

int somefunc(float timeout);

I doubled a definition in the pxd file:我将pxd文件中的定义加倍:

int somefunc(float timeout) nogil;

But any attempt to call the function with nogil leads to the same error when cythonizing the pyx file:但是任何尝试使用 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

I also tried calling it with a ctype, which causes the same error.我还尝试使用 ctype 调用它,这会导致相同的错误。

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

Only using a float literal works.仅使用浮点文字有效。 What is the right way to call this function with an actual Python variable?使用实际 Python 变量调用此 function 的正确方法是什么?

When you look at the generated code for当您查看生成的代码时

timeout = 1.0
Q.somefunc(timeout)

you will see, that timeout is PyObject and __pyx_PyFloat_AsFloat is called to convert is to cdef-float.你会看到, timeoutPyObject并且__pyx_PyFloat_AsFloat来转换为 cdef-float。 However during this conversion an exception can be raised and for this the gil is needed - thus the error message.但是,在此转换过程中,可能会引发异常,为此需要 gil - 因此会出现错误消息。

The solution would be to force coercion to float before the nogil-block:解决方案是强制强制在 nogil-block 之前float

cdef float timeout = 1.0
with nogil:
    Q.somefunc(timeout)

now timeout is already cdef-float and no conversion is needed in the nogil-block.现在 timeout 已经是 cdef-float 并且 nogil-block 中不需要转换。


Slightly unrelated: I cannot see the code and what Q is, but most of the time it is wrong to release gil when letting C/C++ code do the work:有点不相关:我看不到代码和Q是什么,但大多数时候在让 C/C++ 代码完成工作时释放 gil 是错误的:

  1. When C/C++ uses openMP for parallelization, holding/not holding GIL doesn't change anything for the C/C++-code (here is an example: https://stackoverflow.com/a/60012137/5769463 ).当 C/C++ 使用 openMP 进行并行化时,持有/不持有 GIL 不会改变 C/C++ 代码的任何内容(这是一个示例: https://stackoverflow.com/a/60012137/5769463 )。

  2. When the thread doesn't hold GIL the other could destroy objects needed for the C/C++-code to work (like Q or other data)当线程不持有 GIL 时,其他线程可能会破坏 C/C++ 代码工作所需的对象(如Q或其他数据)

  3. We can release GIL when working with objects implementing buffer protocol, because buffer protocol (when correctly implemented) locks the buffer and the buffer cannot be destroyed from another Python-Thread.我们可以在处理实现缓冲区协议的对象时释放 GIL,因为缓冲区协议(正确实现时)会锁定缓冲区,并且缓冲区不能从另一个 Python 线程中销毁。 Other Python objects have no such locking built-in.其他 Python 对象没有这种内置锁定。

But as noted above, it might not apply to your code.但如上所述,它可能不适用于您的代码。

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

相关问题 Cython错误:没有GIL就不允许来自Python的强制 - Cython error: Coercion from Python not allowed without the GIL 在没有 GIL 的情况下不允许来自 Python 的强制,并行使用 arrays(Cython 中的多线程) - Coercion from Python not allowed without the GIL, using arrays in parallel (multithreading in Cython) 使用并行性崩溃的程序:在没有 gil 的情况下不允许丢弃拥有的 Python 对象 - Program using parallelism crashing: Discarding owned Python object not allowed without gil 在 Python C 扩展中使用来自 PyObjects 的数据而不持有 GIL - using data from PyObjects in Python C Extension without holding the GIL 有没有办法在不使用 python GIL 的情况下进行序列化/反序列化 - Is there a way to serialize/deserialize without engaging the python GIL Python:在没有GIL的情况下绘制一些数据(matplotlib) - Python: Plot some data (matplotlib) without GIL Python 中的任何类型,无需自动强制 - Any-type in Python without automatic coercion 在 python 中安排定期的非阻塞任务而不处理 GIL - Schedule periodic non-blocking tasks in python without dealing with the GIL 在没有 GIL 的情况下在 Cython 中并行化 - Parallelize in Cython without GIL 来自PEP-492的协同程序是否绕过Python 3.5中的GIL? - Do coroutines from PEP-492 bypass the GIL in Python 3.5?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM