[英]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)
你會看到, timeout
是PyObject
並且__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 是錯誤的:
當 C/C++ 使用 openMP 進行並行化時,持有/不持有 GIL 不會改變 C/C++ 代碼的任何內容(這是一個示例: https://stackoverflow.com/a/60012137/5769463 )。
當線程不持有 GIL 時,其他線程可能會破壞 C/C++ 代碼工作所需的對象(如Q
或其他數據)
我們可以在處理實現緩沖區協議的對象時釋放 GIL,因為緩沖區協議(正確實現時)會鎖定緩沖區,並且緩沖區不能從另一個 Python 線程中銷毀。 其他 Python 對象沒有這種內置鎖定。
但如上所述,它可能不適用於您的代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.