Skip to content

Commit 32502da

Browse files
[3.12] gh-107305: Update the C-API Docs for PEP 684 (gh-107324) (gh-107402)
gh-107305: Update the C-API Docs for PEP 684 (gh-107324) (cherry picked from commit c0b81c4) Co-authored-by: Eric Snow <[email protected]>
1 parent 0f42f41 commit 32502da

File tree

2 files changed

+197
-15
lines changed

2 files changed

+197
-15
lines changed

Doc/c-api/init.rst

+194-15
Original file line numberDiff line numberDiff line change
@@ -1494,7 +1494,95 @@ You can switch between sub-interpreters using the :c:func:`PyThreadState_Swap`
14941494
function. You can create and destroy them using the following functions:
14951495
14961496
1497-
.. c:function:: PyThreadState* Py_NewInterpreter()
1497+
.. c:type:: PyInterpreterConfig
1498+
1499+
Structure containing most parameters to configure a sub-interpreter.
1500+
Its values are used only in :c:func:`Py_NewInterpreterFromConfig` and
1501+
never modified by the runtime.
1502+
1503+
.. versionadded:: 3.12
1504+
1505+
Structure fields:
1506+
1507+
.. c:member:: int use_main_obmalloc
1508+
1509+
If this is ``0`` then the sub-interpreter will use its own
1510+
"object" allocator state.
1511+
Otherwise it will use (share) the main interpreter's.
1512+
1513+
If this is ``0`` then
1514+
:c:member:`~PyInterpreterConfig.check_multi_interp_extensions`
1515+
must be ``1`` (non-zero).
1516+
If this is ``1`` then :c:member:`~PyInterpreterConfig.gil`
1517+
must not be :c:macro:`PyInterpreterConfig_OWN_GIL`.
1518+
1519+
.. c:member:: int allow_fork
1520+
1521+
If this is ``0`` then the runtime will not support forking the
1522+
process in any thread where the sub-interpreter is currently active.
1523+
Otherwise fork is unrestricted.
1524+
1525+
Note that the :mod:`subprocess` module still works
1526+
when fork is disallowed.
1527+
1528+
.. c:member:: int allow_exec
1529+
1530+
If this is ``0`` then the runtime will not support replacing the
1531+
current process via exec (e.g. :func:`os.execv`) in any thread
1532+
where the sub-interpreter is currently active.
1533+
Otherwise exec is unrestricted.
1534+
1535+
Note that the :mod:`subprocess` module still works
1536+
when exec is disallowed.
1537+
1538+
.. c:member:: int allow_threads
1539+
1540+
If this is ``0`` then the sub-interpreter's :mod:`threading` module
1541+
won't create threads.
1542+
Otherwise threads are allowed.
1543+
1544+
.. c:member:: int allow_daemon_threads
1545+
1546+
If this is ``0`` then the sub-interpreter's :mod:`threading` module
1547+
won't create daemon threads.
1548+
Otherwise daemon threads are allowed (as long as
1549+
:c:member:`~PyInterpreterConfig.allow_threads` is non-zero).
1550+
1551+
.. c:member:: int check_multi_interp_extensions
1552+
1553+
If this is ``0`` then all extension modules may be imported,
1554+
including legacy (single-phase init) modules,
1555+
in any thread where the sub-interpreter is currently active.
1556+
Otherwise only multi-phase init extension modules
1557+
(see :pep:`489`) may be imported.
1558+
1559+
This must be ``1`` (non-zero) if
1560+
:c:member:`~PyInterpreterConfig.use_main_obmalloc` is ``0``.
1561+
1562+
.. c:member:: int gil
1563+
1564+
This determines the operation of the GIL for the sub-interpreter.
1565+
It may be one of the following:
1566+
1567+
.. c:namespace:: NULL
1568+
1569+
.. c:macro:: PyInterpreterConfig_DEFAULT_GIL
1570+
1571+
Use the default selection (:c:macro:`PyInterpreterConfig_SHARED_GIL`).
1572+
1573+
.. c:macro:: PyInterpreterConfig_SHARED_GIL
1574+
1575+
Use (share) the main interpreter's GIL.
1576+
1577+
.. c:macro:: PyInterpreterConfig_OWN_GIL
1578+
1579+
Use the sub-interpreter's own GIL.
1580+
1581+
If this is :c:macro:`PyInterpreterConfig_OWN_GIL` then
1582+
:c:member:`PyInterpreterConfig.use_main_obmalloc` must be ``0``.
1583+
1584+
1585+
.. c:function:: PyStatus Py_NewInterpreterFromConfig(PyThreadState **tstate_p, const PyInterpreterConfig *config)
14981586
14991587
.. index::
15001588
pair: module; builtins
@@ -1514,16 +1602,47 @@ function. You can create and destroy them using the following functions:
15141602
``sys.stdout`` and ``sys.stderr`` (however these refer to the same underlying
15151603
file descriptors).
15161604
1517-
The return value points to the first thread state created in the new
1605+
The given *config* controls the options with which the interpreter
1606+
is initialized.
1607+
1608+
Upon success, *tstate_p* will be set to the first thread state
1609+
created in the new
15181610
sub-interpreter. This thread state is made in the current thread state.
15191611
Note that no actual thread is created; see the discussion of thread states
1520-
below. If creation of the new interpreter is unsuccessful, ``NULL`` is
1521-
returned; no exception is set since the exception state is stored in the
1522-
current thread state and there may not be a current thread state. (Like all
1523-
other Python/C API functions, the global interpreter lock must be held before
1524-
calling this function and is still held when it returns; however, unlike most
1525-
other Python/C API functions, there needn't be a current thread state on
1526-
entry.)
1612+
below. If creation of the new interpreter is unsuccessful,
1613+
*tstate_p* is set to ``NULL``;
1614+
no exception is set since the exception state is stored in the
1615+
current thread state and there may not be a current thread state.
1616+
1617+
Like all other Python/C API functions, the global interpreter lock
1618+
must be held before calling this function and is still held when it
1619+
returns. Likewise a current thread state must be set on entry. On
1620+
success, the returned thread state will be set as current. If the
1621+
sub-interpreter is created with its own GIL then the GIL of the
1622+
calling interpreter will be released. When the function returns,
1623+
the new interpreter's GIL will be held by the current thread and
1624+
the previously interpreter's GIL will remain released here.
1625+
1626+
.. versionadded:: 3.12
1627+
1628+
Sub-interpreters are most effective when isolated from each other,
1629+
with certain functionality restricted::
1630+
1631+
PyInterpreterConfig config = {
1632+
.use_main_obmalloc = 0,
1633+
.allow_fork = 0,
1634+
.allow_exec = 0,
1635+
.allow_threads = 1,
1636+
.allow_daemon_threads = 0,
1637+
.check_multi_interp_extensions = 1,
1638+
.gil = PyInterpreterConfig_OWN_GIL,
1639+
};
1640+
PyThreadState *tstate = Py_NewInterpreterFromConfig(&config);
1641+
1642+
Note that the config is used only briefly and does not get modified.
1643+
During initialization the config's values are converted into various
1644+
:c:type:`PyInterpreterState` values. A read-only copy of the config
1645+
may be stored internally on the :c:type:`PyInterpreterState`.
15271646
15281647
.. index::
15291648
single: Py_FinalizeEx()
@@ -1558,19 +1677,79 @@ function. You can create and destroy them using the following functions:
15581677
.. index:: single: close() (in module os)
15591678
15601679
1680+
.. c:function:: PyThreadState* Py_NewInterpreter(void)
1681+
1682+
.. index::
1683+
pair: module; builtins
1684+
pair: module; __main__
1685+
pair: module; sys
1686+
single: stdout (in module sys)
1687+
single: stderr (in module sys)
1688+
single: stdin (in module sys)
1689+
1690+
Create a new sub-interpreter. This is essentially just a wrapper
1691+
around :c:func:`Py_NewInterpreterFromConfig` with a config that
1692+
preserves the existing behavior. The result is an unisolated
1693+
sub-interpreter that shares the main interpreter's GIL, allows
1694+
fork/exec, allows daemon threads, and allows single-phase init
1695+
modules.
1696+
1697+
15611698
.. c:function:: void Py_EndInterpreter(PyThreadState *tstate)
15621699
15631700
.. index:: single: Py_FinalizeEx()
15641701
1565-
Destroy the (sub-)interpreter represented by the given thread state. The given
1566-
thread state must be the current thread state. See the discussion of thread
1567-
states below. When the call returns, the current thread state is ``NULL``. All
1568-
thread states associated with this interpreter are destroyed. (The global
1569-
interpreter lock must be held before calling this function and is still held
1570-
when it returns.) :c:func:`Py_FinalizeEx` will destroy all sub-interpreters that
1702+
Destroy the (sub-)interpreter represented by the given thread state.
1703+
The given thread state must be the current thread state. See the
1704+
discussion of thread states below. When the call returns,
1705+
the current thread state is ``NULL``. All thread states associated
1706+
with this interpreter are destroyed. The global interpreter lock
1707+
used by the target interpreter must be held before calling this
1708+
function. No GIL is held when it returns.
1709+
1710+
:c:func:`Py_FinalizeEx` will destroy all sub-interpreters that
15711711
haven't been explicitly destroyed at that point.
15721712
15731713
1714+
A Per-Interpreter GIL
1715+
---------------------
1716+
1717+
Using :c:func:`Py_NewInterpreterFromConfig` you can create
1718+
a sub-interpreter that is completely isolated from other interpreters,
1719+
including having its own GIL. The most important benefit of this
1720+
isolation is that such an interpreter can execute Python code without
1721+
being blocked by other interpreters or blocking any others. Thus a
1722+
single Python process can truly take advantage of multiple CPU cores
1723+
when running Python code. The isolation also encourages a different
1724+
approach to concurrency than that of just using threads.
1725+
(See :pep:`554`.)
1726+
1727+
Using an isolated interpreter requires vigilance in preserving that
1728+
isolation. That especially means not sharing any objects or mutable
1729+
state without guarantees about thread-safety. Even objects that are
1730+
otherwise immutable (e.g. ``None``, ``(1, 5)``) can't normally be shared
1731+
because of the refcount. One simple but less-efficient approach around
1732+
this is to use a global lock around all use of some state (or object).
1733+
Alternately, effectively immutable objects (like integers or strings)
1734+
can be made safe in spite of their refcounts by making them "immortal".
1735+
In fact, this has been done for the builtin singletons, small integers,
1736+
and a number of other builtin objects.
1737+
1738+
If you preserve isolation then you will have access to proper multi-core
1739+
computing without the complications that come with free-threading.
1740+
Failure to preserve isolation will expose you to the full consequences
1741+
of free-threading, including races and hard-to-debug crashes.
1742+
1743+
Aside from that, one of the main challenges of using multiple isolated
1744+
interpreters is how to communicate between them safely (not break
1745+
isolation) and efficiently. The runtime and stdlib do not provide
1746+
any standard approach to this yet. A future stdlib module would help
1747+
mitigate the effort of preserving isolation and expose effective tools
1748+
for communicating (and sharing) data between interpreters.
1749+
1750+
.. versionadded:: 3.12
1751+
1752+
15741753
Bugs and caveats
15751754
----------------
15761755
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Add documentation for :c:type:`PyInterpreterConfig` and
2+
:c:func:`Py_NewInterpreterFromConfig`. Also clarify some of the nearby docs
3+
relative to per-interpreter GIL.

0 commit comments

Comments
 (0)