Struct pyo3::once_cell::GILOnceCell [−][src]
pub struct GILOnceCell<T>(_);
Expand description
A write-once cell similar to once_cell::OnceCell
.
Unlike once_cell::sync
which blocks threads to achieve thread safety, this implementation
uses the Python GIL to mediate concurrent access. This helps in cases where once_sync
or
lazy_static
’s synchronization strategy can lead to deadlocks when interacting with the Python
GIL. For an example, see the FAQ section of the guide.
Example
The following example shows how to use GILOnceCell
to share a reference to a Python list
between threads:
use pyo3::prelude::*;
use pyo3::types::PyList;
use pyo3::once_cell::GILOnceCell;
static LIST_CELL: GILOnceCell<Py<PyList>> = GILOnceCell::new();
pub fn get_shared_list(py: Python) -> &PyList {
LIST_CELL
.get_or_init(py, || PyList::empty(py).into())
.as_ref(py)
}
Implementations
Get a reference to the contained value, or None
if the cell has not yet been written.
Get a reference to the contained value, initializing it if needed using the provided closure.
Note that:
- reentrant initialization can cause a stack overflow.
- if f() temporarily releases the GIL (e.g. by calling
Python::import
) then it is possible (and well-defined) that a second thread may also call get_or_init and begin callingf()
. Even when this happensGILOnceCell
guarantees that only one write to the cell ever occurs - other threads will simply discard the value they compute and return the result of the first complete computation. - if f() does not release the GIL and does not panic, it is guaranteed to be called
exactly once, even if multiple threads attempt to call
get_or_init
- if f() can panic but still does not release the GIL, it may be called multiple times, but it is guaranteed that f() will never be called concurrently
Get the contents of the cell mutably. This is only possible if the reference to the cell is unique.