summaryrefslogtreecommitdiffstats
path: root/Doc/c-api
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2019-11-15 21:28:54 (GMT)
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2019-11-15 21:28:54 (GMT)
commit73cdb0c6b2c3861e034004cdc57be5e726876078 (patch)
tree8ba4d48dea974597fd97525cf50b65b688ef6a75 /Doc/c-api
parentabde52cd8e31830bfc06c5803221faae6172104a (diff)
downloadcpython-73cdb0c6b2c3861e034004cdc57be5e726876078.zip
cpython-73cdb0c6b2c3861e034004cdc57be5e726876078.tar.gz
cpython-73cdb0c6b2c3861e034004cdc57be5e726876078.tar.bz2
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
Diffstat (limited to 'Doc/c-api')
-rw-r--r--Doc/c-api/init.rst23
-rw-r--r--Doc/c-api/sys.rst18
2 files changed, 40 insertions, 1 deletions
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index dc30e49..86bf7f9 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -769,9 +769,19 @@ supports the creation of additional interpreters (using
:c:func:`Py_NewInterpreter`), but mixing multiple interpreters and the
: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
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
this for :func:`os.fork` by acquiring the locks it uses internally before
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
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
--------------
diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst
index 212f4d1..d3bbee2 100644
--- a/Doc/c-api/sys.rst
+++ b/Doc/c-api/sys.rst
@@ -33,6 +33,12 @@ Operating System Utilities
that clones the current process.
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
@@ -44,6 +50,12 @@ Operating System Utilities
of whether process cloning was successful.
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
@@ -55,6 +67,12 @@ Operating System Utilities
any chance the process will call back into the Python interpreter.
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
.. seealso::