簡體   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