Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
1874f8fa
Unverified
Commit
1874f8fa
authored
Sep 14, 2022
by
Dustin Spicuzza
Committed by
GitHub
Sep 14, 2022
Browse files
Clarify GIL documentation (#4057)
parent
8524b20c
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
33 additions
and
7 deletions
+33
-7
docs/advanced/misc.rst
docs/advanced/misc.rst
+33
-7
No files found.
docs/advanced/misc.rst
View file @
1874f8fa
...
@@ -39,15 +39,42 @@ The ``PYBIND11_MAKE_OPAQUE`` macro does *not* require the above workarounds.
...
@@ -39,15 +39,42 @@ The ``PYBIND11_MAKE_OPAQUE`` macro does *not* require the above workarounds.
Global Interpreter Lock (GIL)
Global Interpreter Lock (GIL)
=============================
=============================
When calling a C++ function from Python, the GIL is always held.
The Python C API dictates that the Global Interpreter Lock (GIL) must always
be held by the current thread to safely access Python objects. As a result,
when Python calls into C++ via pybind11 the GIL must be held, and pybind11
will never implicitly release the GIL.
.. code-block:: cpp
void my_function() {
/* GIL is held when this function is called from Python */
}
PYBIND11_MODULE(example, m) {
m.def("my_function", &my_function);
}
pybind11 will ensure that the GIL is held when it knows that it is calling
Python code. For example, if a Python callback is passed to C++ code via
``std::function``, when C++ code calls the function the built-in wrapper
will acquire the GIL before calling the Python callback. Similarly, the
``PYBIND11_OVERRIDE`` family of macros will acquire the GIL before calling
back into Python.
When writing C++ code that is called from other C++ code, if that code accesses
Python state, it must explicitly acquire and release the GIL.
The classes :class:`gil_scoped_release` and :class:`gil_scoped_acquire` can be
The classes :class:`gil_scoped_release` and :class:`gil_scoped_acquire` can be
used to acquire and release the global interpreter lock in the body of a C++
used to acquire and release the global interpreter lock in the body of a C++
function call. In this way, long-running C++ code can be parallelized using
function call. In this way, long-running C++ code can be parallelized using
multiple Python threads. Taking :ref:`overriding_virtuals` as an example, this
multiple Python threads, **but great care must be taken** when any
:class:`gil_scoped_release` appear: if there is any way that the C++ code
can access Python objects, :class:`gil_scoped_acquire` should be used to
reacquire the GIL. Taking :ref:`overriding_virtuals` as an example, this
could be realized as follows (important changes highlighted):
could be realized as follows (important changes highlighted):
.. code-block:: cpp
.. code-block:: cpp
:emphasize-lines: 8,
9,31
,3
2
:emphasize-lines: 8,
30
,3
1
class PyAnimal : public Animal {
class PyAnimal : public Animal {
public:
public:
...
@@ -56,9 +83,7 @@ could be realized as follows (important changes highlighted):
...
@@ -56,9 +83,7 @@ could be realized as follows (important changes highlighted):
/* Trampoline (need one for each virtual function) */
/* Trampoline (need one for each virtual function) */
std::string go(int n_times) {
std::string go(int n_times) {
/* Acquire GIL before calling Python code */
/* PYBIND11_OVERRIDE_PURE will acquire the GIL before accessing Python state */
py::gil_scoped_acquire acquire;
PYBIND11_OVERRIDE_PURE(
PYBIND11_OVERRIDE_PURE(
std::string, /* Return type */
std::string, /* Return type */
Animal, /* Parent class */
Animal, /* Parent class */
...
@@ -78,7 +103,8 @@ could be realized as follows (important changes highlighted):
...
@@ -78,7 +103,8 @@ could be realized as follows (important changes highlighted):
.def(py::init<>());
.def(py::init<>());
m.def("call_go", [](Animal *animal) -> std::string {
m.def("call_go", [](Animal *animal) -> std::string {
/* Release GIL before calling into (potentially long-running) C++ code */
// GIL is held when called from Python code. Release GIL before
// calling into (potentially long-running) C++ code
py::gil_scoped_release release;
py::gil_scoped_release release;
return call_go(animal);
return call_go(animal);
});
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment