Frequently Asked Questions / Troubleshooting
I'm experiencing deadlocks using PyO3 with lazy_static or once_cell!
lazy_static and once_cell::sync both use locks to ensure that initialization is performed only by a single thread. Because the Python GIL is an additional lock this can lead to deadlocks in the following way:
- A thread (thread A) which has acquired the Python GIL starts initialization of a
lazy_staticvalue. - The initialization code calls some Python API which temporarily releases the GIL e.g.
Python::import. - Another thread (thread B) acquires the Python GIL and attempts to access the same
lazy_staticvalue. - Thread B is blocked, because it waits for
lazy_static's initialization to lock to release. - Thread A is blocked, because it waits to re-aquire the GIL which thread B still holds.
- Deadlock.
PyO3 provides a struct GILOnceCell which works equivalently to OnceCell but relies solely on the Python GIL for thread safety. This means it can be used in place of lazy_static or once_cell where you are experiencing the deadlock described above. See the documentation for GILOnceCell for an example how to use it.
I can't run cargo test: I'm having linker issues like "Symbol not found" or "Undefined reference to _PyExc_SystemError"!
Currently, #341 causes cargo test to fail with linking errors when the extension-module feature is activated. For now you can work around this by making the extension-module feature optional and running the tests with cargo test --no-default-features:
[dependencies.pyo3] version = "*" [features] extension-module = ["pyo3/extension-module"] default = ["extension-module"]