mirror of
https://github.com/pybind/pybind11.git
synced 2026-04-19 22:39:09 +00:00
docs: more warnings about locking and the GIL (#5689)
* docs: more warnings about locking and the GIL Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * fix require → reacquire typo --------- Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> Co-authored-by: Ralf W. Grosse-Kunstleve <rwgkio@gmail.com>
This commit is contained in:
@@ -299,9 +299,17 @@ However, the module is no longer free-threading safe, for the same reason as
|
||||
before, because the calculation is not synchronized. We can synchronize it
|
||||
using a Python critical section. This will do nothing if not in free-threaded
|
||||
Python. You can have it lock one or two Python objects. You cannot nest it.
|
||||
(Note: In Python 3.13t, Python re-locks if you enter a critical section again,
|
||||
which happens in various places. This was optimized away in 3.14+. Use a
|
||||
``std::mutex`` instead if this is a problem).
|
||||
|
||||
.. warning::
|
||||
|
||||
When using a ``py::scoped_critical_section``, make sure it is not nested and
|
||||
that no other synchronization primitives (such as a ``std::mutex``) are
|
||||
held, which could lead to deadlocks. In 3.13, taking the same lock causes it
|
||||
to release then reacquire, which means you can't use it to, for example, read
|
||||
and write to a dictionary, because the dictionary uses a critical section
|
||||
internally in CPython. Use a ``std::mutex`` instead if you need this on
|
||||
Python 3.13. In 3.14, taking a lock on a locked object no longer releases
|
||||
and relocks as an optimization, which also fixes this case.
|
||||
|
||||
.. code-block:: cpp
|
||||
:emphasize-lines: 1,4,8
|
||||
|
||||
@@ -365,8 +365,13 @@ TEST_CASE("Threads") {
|
||||
py::gil_scoped_acquire gil{};
|
||||
#ifdef Py_GIL_DISABLED
|
||||
# if PY_VERSION_HEX < 0x030E0000
|
||||
// This will not run with the GIL, so it won't deadlock. That's
|
||||
// because of how we run our tests. Be more careful of
|
||||
// deadlocks if the "free-threaded" GIL could be enabled (at
|
||||
// runtime).
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
# else
|
||||
// CPython's thread-safe API in no-GIL mode.
|
||||
py::scoped_critical_section lock(locals);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user