bpo-38816: Add notes in the C-API docs about fork in subinterpreters. (GH-17176)
The C-API docs are a bit sparse on the interplay between C `fork()` and the CPython runtime. This change adds some more information on the subject. https://bugs.python.org/issue38816
This commit is contained in:
parent
abde52cd8e
commit
73cdb0c6b2
|
@ -769,9 +769,19 @@ supports the creation of additional interpreters (using
|
||||||
:c:func:`Py_NewInterpreter`), but mixing multiple interpreters and the
|
:c:func:`Py_NewInterpreter`), but mixing multiple interpreters and the
|
||||||
:c:func:`PyGILState_\*` API is unsupported.
|
:c:func:`PyGILState_\*` API is unsupported.
|
||||||
|
|
||||||
|
|
||||||
|
.. _fork-and-threads:
|
||||||
|
|
||||||
|
Cautions about fork()
|
||||||
|
---------------------
|
||||||
|
|
||||||
Another important thing to note about threads is their behaviour in the face
|
Another important thing to note about threads is their behaviour in the face
|
||||||
of the C :c:func:`fork` call. On most systems with :c:func:`fork`, after a
|
of the C :c:func:`fork` call. On most systems with :c:func:`fork`, after a
|
||||||
process forks only the thread that issued the fork will exist. That also
|
process forks only the thread that issued the fork will exist. This has a
|
||||||
|
concrete impact both on how locks must be handled and on all stored state
|
||||||
|
in CPython's runtime.
|
||||||
|
|
||||||
|
The fact that only the "current" thread remains
|
||||||
means any locks held by other threads will never be released. Python solves
|
means any locks held by other threads will never be released. Python solves
|
||||||
this for :func:`os.fork` by acquiring the locks it uses internally before
|
this for :func:`os.fork` by acquiring the locks it uses internally before
|
||||||
the fork, and releasing them afterwards. In addition, it resets any
|
the fork, and releasing them afterwards. In addition, it resets any
|
||||||
|
@ -786,6 +796,17 @@ being held by a thread that is defunct after the fork.
|
||||||
:c:func:`PyOS_AfterFork_Child` tries to reset the necessary locks, but is not
|
:c:func:`PyOS_AfterFork_Child` tries to reset the necessary locks, but is not
|
||||||
always able to.
|
always able to.
|
||||||
|
|
||||||
|
The fact that all other threads go away also means that CPython's
|
||||||
|
runtime state there must be cleaned up properly, which :func:`os.fork`
|
||||||
|
does. This means finalizing all other :c:type:`PyThreadState` objects
|
||||||
|
belonging to the current interpreter and all other
|
||||||
|
:c:type:`PyInterpreterState` objects. Due to this and the special
|
||||||
|
nature of the :ref:`"main" interpreter <sub-interpreter-support>`,
|
||||||
|
:c:func:`fork` should only be called in that interpreter's "main"
|
||||||
|
thread, where the CPython global runtime was originally initialized.
|
||||||
|
The only exception is if :c:func:`exec` will be called immediately
|
||||||
|
after.
|
||||||
|
|
||||||
|
|
||||||
High-level API
|
High-level API
|
||||||
--------------
|
--------------
|
||||||
|
|
|
@ -33,6 +33,12 @@ Operating System Utilities
|
||||||
that clones the current process.
|
that clones the current process.
|
||||||
Only available on systems where :c:func:`fork` is defined.
|
Only available on systems where :c:func:`fork` is defined.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
The C :c:func:`fork` call should only be made from the
|
||||||
|
:ref:`"main" thread <fork-and-threads>` (of the
|
||||||
|
:ref:`"main" interpreter <sub-interpreter-support>`). The same is
|
||||||
|
true for ``PyOS_BeforeFork()``.
|
||||||
|
|
||||||
.. versionadded:: 3.7
|
.. versionadded:: 3.7
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,6 +50,12 @@ Operating System Utilities
|
||||||
of whether process cloning was successful.
|
of whether process cloning was successful.
|
||||||
Only available on systems where :c:func:`fork` is defined.
|
Only available on systems where :c:func:`fork` is defined.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
The C :c:func:`fork` call should only be made from the
|
||||||
|
:ref:`"main" thread <fork-and-threads>` (of the
|
||||||
|
:ref:`"main" interpreter <sub-interpreter-support>`). The same is
|
||||||
|
true for ``PyOS_AfterFork_Parent()``.
|
||||||
|
|
||||||
.. versionadded:: 3.7
|
.. versionadded:: 3.7
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,6 +67,12 @@ Operating System Utilities
|
||||||
any chance the process will call back into the Python interpreter.
|
any chance the process will call back into the Python interpreter.
|
||||||
Only available on systems where :c:func:`fork` is defined.
|
Only available on systems where :c:func:`fork` is defined.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
The C :c:func:`fork` call should only be made from the
|
||||||
|
:ref:`"main" thread <fork-and-threads>` (of the
|
||||||
|
:ref:`"main" interpreter <sub-interpreter-support>`). The same is
|
||||||
|
true for ``PyOS_AfterFork_Child()``.
|
||||||
|
|
||||||
.. versionadded:: 3.7
|
.. versionadded:: 3.7
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Provides more details about the interaction between :c:func:`fork` and
|
||||||
|
CPython's runtime, focusing just on the C-API. This includes cautions
|
||||||
|
about where :c:func:`fork` should and shouldn't be called.
|
Loading…
Reference in New Issue