Skip to content

Commit 1874f8f

Browse files
authored
Clarify GIL documentation (#4057)
1 parent 8524b20 commit 1874f8f

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

docs/advanced/misc.rst

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,42 @@ The ``PYBIND11_MAKE_OPAQUE`` macro does *not* require the above workarounds.
3939
Global Interpreter Lock (GIL)
4040
=============================
4141

42-
When calling a C++ function from Python, the GIL is always held.
42+
The Python C API dictates that the Global Interpreter Lock (GIL) must always
43+
be held by the current thread to safely access Python objects. As a result,
44+
when Python calls into C++ via pybind11 the GIL must be held, and pybind11
45+
will never implicitly release the GIL.
46+
47+
.. code-block:: cpp
48+
49+
void my_function() {
50+
/* GIL is held when this function is called from Python */
51+
}
52+
53+
PYBIND11_MODULE(example, m) {
54+
m.def("my_function", &my_function);
55+
}
56+
57+
pybind11 will ensure that the GIL is held when it knows that it is calling
58+
Python code. For example, if a Python callback is passed to C++ code via
59+
``std::function``, when C++ code calls the function the built-in wrapper
60+
will acquire the GIL before calling the Python callback. Similarly, the
61+
``PYBIND11_OVERRIDE`` family of macros will acquire the GIL before calling
62+
back into Python.
63+
64+
When writing C++ code that is called from other C++ code, if that code accesses
65+
Python state, it must explicitly acquire and release the GIL.
66+
4367
The classes :class:`gil_scoped_release` and :class:`gil_scoped_acquire` can be
4468
used to acquire and release the global interpreter lock in the body of a C++
4569
function call. In this way, long-running C++ code can be parallelized using
46-
multiple Python threads. Taking :ref:`overriding_virtuals` as an example, this
70+
multiple Python threads, **but great care must be taken** when any
71+
:class:`gil_scoped_release` appear: if there is any way that the C++ code
72+
can access Python objects, :class:`gil_scoped_acquire` should be used to
73+
reacquire the GIL. Taking :ref:`overriding_virtuals` as an example, this
4774
could be realized as follows (important changes highlighted):
4875

4976
.. code-block:: cpp
50-
:emphasize-lines: 8,9,31,32
77+
:emphasize-lines: 8,30,31
5178
5279
class PyAnimal : public Animal {
5380
public:
@@ -56,9 +83,7 @@ could be realized as follows (important changes highlighted):
5683
5784
/* Trampoline (need one for each virtual function) */
5885
std::string go(int n_times) {
59-
/* Acquire GIL before calling Python code */
60-
py::gil_scoped_acquire acquire;
61-
86+
/* PYBIND11_OVERRIDE_PURE will acquire the GIL before accessing Python state */
6287
PYBIND11_OVERRIDE_PURE(
6388
std::string, /* Return type */
6489
Animal, /* Parent class */
@@ -78,7 +103,8 @@ could be realized as follows (important changes highlighted):
78103
.def(py::init<>());
79104
80105
m.def("call_go", [](Animal *animal) -> std::string {
81-
/* Release GIL before calling into (potentially long-running) C++ code */
106+
// GIL is held when called from Python code. Release GIL before
107+
// calling into (potentially long-running) C++ code
82108
py::gil_scoped_release release;
83109
return call_go(animal);
84110
});

0 commit comments

Comments
 (0)