forked from python/cpython
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pythongh-124370: Add "howto" for free-threaded Python
This is a guide aimed at people writing Python code, as oppposed to the existing guide for C API extension authors.
- Loading branch information
Showing
3 changed files
with
122 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
.. _freethreading-python-howto: | ||
|
||
********************************* | ||
Python Support for Free Threading | ||
********************************* | ||
|
||
Starting with the 3.13 release, CPython has experimental support for running | ||
with the :term:`global interpreter lock` (GIL) disabled in a configuration | ||
called :term:`free threading`. This document describes the implications of | ||
free threading for Python code. See :ref:`freethreading-extensions-howto` for | ||
information on how to write C extensions that support the free-threaded build. | ||
|
||
|
||
Installation | ||
============ | ||
|
||
Starting with Python 3.13.0b2, the offical macOS and Windows installers | ||
optionally support installing free-threaded Python binaries. The installers | ||
are available at https://www.python.org/downloads/. | ||
|
||
.. seealso:: | ||
|
||
`Installing a Free-Threaded Python | ||
<https://py-free-threading.github.io/installing_cpython/>`_: | ||
A community-maintained installation guide for installing free-threaded | ||
Python. | ||
|
||
|
||
Identifying Free-Threaded Python | ||
================================ | ||
|
||
The free-threaded build of CPython can optionally run with the global | ||
interpreter lock enabled, such as when :envvar:`PYTHON_GIL` is set to ``1``, | ||
or when importing an extension module that requires the GIL. | ||
|
||
The :func:`sys._is_gil_enabled` function will return ``False`` if the global | ||
interpreter lock is currently disabled. This is the recommended mechanism for | ||
decisions like whether to use multithreading or multiprocessing. | ||
|
||
The ``sysconfig.get_config_var("Py_GIL_DISABLED")`` configuration variable can | ||
be used to determine whether the build supports free threading. If the variable | ||
is set to ``1``, then the build supports free threading. This is the recommended | ||
mechanism for decisions related to the build configuration. | ||
|
||
|
||
Thread Safety | ||
============= | ||
|
||
The free-threaded build of CPython aims to provide similar thread-safety | ||
behavior at the Python level to the GIL-enabled build. Built-in | ||
types like :class:`dict`, :class:`list`, and :class:`set` use internal locks | ||
to protect against concurrent modifications in ways that behave similarly to | ||
the GIL. However, Python has not historically guaranteed specific behavior for | ||
concurrent modifications to these built-in types, so this should be treated | ||
as a description of the current implementation, not a guarantee of future | ||
behavior. | ||
|
||
.. note:: | ||
|
||
It's recommended to use the :class:`threading.Lock` or other synchronization | ||
primitives instead of relying on the internal locks of built-in types, when | ||
possible. | ||
|
||
|
||
|
||
Known Limitations | ||
================= | ||
|
||
This section describes known limitations of the free-threaded CPython build. | ||
|
||
Immortalization | ||
--------------- | ||
|
||
The free-threaded build of the 3.13 release makes some objects :term:`immortal` | ||
in order to avoid reference count contention that would prevent efficient | ||
multi-threaded scaling. This means that these objects are never deallocated. | ||
This expected to be addressed in the upcoming 3.14 release with | ||
`deferred reference counting <https://peps.python.org/pep-0703/#deferred-reference-counting>`_. | ||
|
||
The objects that are immortalized are: | ||
|
||
* :ref:`function <user-defined-funcs>` objects declared at the module level | ||
* :ref:`method <instance-methods>` descriptors | ||
* :ref:`code <code-objects>` objects | ||
* :term:`module` objects and their dictionaries | ||
* :ref:`classes <classes>` (type objects) | ||
|
||
The immortalization of these objects happens the first time a thread is started | ||
after the main thread. | ||
|
||
Additionally, numeric and string literals in the code as well as strings | ||
returned by :func:`sys.intern` are also interned. This behavior is expected to | ||
remainin the 3.14 free-threaded build. | ||
|
||
|
||
Frame Objects | ||
------------- | ||
|
||
It is not safe to access :ref:`frame <frame-objects>` objects from other | ||
threads. This means that :func:`sys._current_frames` is generally not safe to | ||
use in a free-threaded build. | ||
|
||
Iterators | ||
--------- | ||
|
||
Sharing the same iterator object between multiple threads is generally not | ||
safe and threads may see duplicate or missing elements when iterating or crash | ||
the interpreter. | ||
|
||
|
||
Single-Threaded Performance | ||
--------------------------- | ||
|
||
The free-threaded build has additional overhead when executing Python code | ||
compared to the default GIL-enabled build. In 3.13, this overhead is about | ||
40% on the `pyperformance <https://pyperformance.readthedocs.io/>`_ suite. | ||
Programs that spend most of the their time in C extensions or I/O will see | ||
less of an impact. This overhead is expected to be reduced in the upcoming | ||
3.14 release. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters