Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-124370: Add "howto" for free-threaded Python #124368

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions Doc/howto/free-threading-python.rst
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.
2 changes: 2 additions & 0 deletions Doc/howto/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Python Library Reference.
isolating-extensions.rst
timerfd.rst
mro.rst
free-threading-python.rst
free-threading-extensions.rst

General:
Expand All @@ -52,6 +53,7 @@ General:
Advanced development:

* :ref:`curses-howto`
* :ref:`freethreading-python-howto`
* :ref:`freethreading-extensions-howto`
* :ref:`isolating-extensions-howto`
* :ref:`python_2.3_mro`
Expand Down
1 change: 1 addition & 0 deletions Doc/reference/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,7 @@ this case, the special read-only attribute :attr:`!__self__` is set to the objec
denoted by *alist*. (The attribute has the same semantics as it does with
:attr:`other instance methods <method.__self__>`.)

.. _classes:

Classes
^^^^^^^
Expand Down
Loading