mirror of
https://github.com/python/cpython.git
synced 2025-08-23 02:04:56 +00:00
[3.14] gh-124210: Add introduction to threading
docs (GH-127046) (#134090)
Co-authored-by: Semyon Moroz <donbarbos@proton.me> Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
This commit is contained in:
parent
dda5dc5f06
commit
fe5636ea96
1 changed files with 89 additions and 25 deletions
|
@ -11,6 +11,52 @@
|
||||||
This module constructs higher-level threading interfaces on top of the lower
|
This module constructs higher-level threading interfaces on top of the lower
|
||||||
level :mod:`_thread` module.
|
level :mod:`_thread` module.
|
||||||
|
|
||||||
|
.. include:: ../includes/wasm-notavail.rst
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
|
||||||
|
The :mod:`!threading` module provides a way to run multiple `threads
|
||||||
|
<https://en.wikipedia.org/wiki/Thread_(computing)>`_ (smaller
|
||||||
|
units of a process) concurrently within a single process. It allows for the
|
||||||
|
creation and management of threads, making it possible to execute tasks in
|
||||||
|
parallel, sharing memory space. Threads are particularly useful when tasks are
|
||||||
|
I/O bound, such as file operations or making network requests,
|
||||||
|
where much of the time is spent waiting for external resources.
|
||||||
|
|
||||||
|
A typical use case for :mod:`!threading` includes managing a pool of worker
|
||||||
|
threads that can process multiple tasks concurrently. Here's a basic example of
|
||||||
|
creating and starting threads using :class:`~threading.Thread`::
|
||||||
|
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
def crawl(link, delay=3):
|
||||||
|
print(f"crawl started for {link}")
|
||||||
|
time.sleep(delay) # Blocking I/O (simulating a network request)
|
||||||
|
print(f"crawl ended for {link}")
|
||||||
|
|
||||||
|
links = [
|
||||||
|
"https://python.org",
|
||||||
|
"https://docs.python.org",
|
||||||
|
"https://peps.python.org",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Start threads for each link
|
||||||
|
threads = []
|
||||||
|
for link in links:
|
||||||
|
# Using `args` to pass positional arguments and `kwargs` for keyword arguments
|
||||||
|
t = threading.Thread(target=crawl, args=(link,), kwargs={"delay": 2})
|
||||||
|
threads.append(t)
|
||||||
|
|
||||||
|
# Start each thread
|
||||||
|
for t in threads:
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
# Wait for all threads to finish
|
||||||
|
for t in threads:
|
||||||
|
t.join()
|
||||||
|
|
||||||
.. versionchanged:: 3.7
|
.. versionchanged:: 3.7
|
||||||
This module used to be optional, it is now always available.
|
This module used to be optional, it is now always available.
|
||||||
|
|
||||||
|
@ -45,7 +91,25 @@ level :mod:`_thread` module.
|
||||||
However, threading is still an appropriate model if you want to run
|
However, threading is still an appropriate model if you want to run
|
||||||
multiple I/O-bound tasks simultaneously.
|
multiple I/O-bound tasks simultaneously.
|
||||||
|
|
||||||
.. include:: ../includes/wasm-notavail.rst
|
GIL and performance considerations
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
Unlike the :mod:`multiprocessing` module, which uses separate processes to
|
||||||
|
bypass the :term:`global interpreter lock` (GIL), the threading module operates
|
||||||
|
within a single process, meaning that all threads share the same memory space.
|
||||||
|
However, the GIL limits the performance gains of threading when it comes to
|
||||||
|
CPU-bound tasks, as only one thread can execute Python bytecode at a time.
|
||||||
|
Despite this, threads remain a useful tool for achieving concurrency in many
|
||||||
|
scenarios.
|
||||||
|
|
||||||
|
As of Python 3.13, experimental :term:`free-threaded <free threading>` builds
|
||||||
|
can disable the GIL, enabling true parallel execution of threads, but this
|
||||||
|
feature is not available by default (see :pep:`703`).
|
||||||
|
|
||||||
|
.. TODO: At some point this feature will become available by default.
|
||||||
|
|
||||||
|
Reference
|
||||||
|
---------
|
||||||
|
|
||||||
This module defines the following functions:
|
This module defines the following functions:
|
||||||
|
|
||||||
|
@ -62,7 +126,7 @@ This module defines the following functions:
|
||||||
|
|
||||||
Return the current :class:`Thread` object, corresponding to the caller's thread
|
Return the current :class:`Thread` object, corresponding to the caller's thread
|
||||||
of control. If the caller's thread of control was not created through the
|
of control. If the caller's thread of control was not created through the
|
||||||
:mod:`threading` module, a dummy thread object with limited functionality is
|
:mod:`!threading` module, a dummy thread object with limited functionality is
|
||||||
returned.
|
returned.
|
||||||
|
|
||||||
The function ``currentThread`` is a deprecated alias for this function.
|
The function ``currentThread`` is a deprecated alias for this function.
|
||||||
|
@ -157,13 +221,13 @@ This module defines the following functions:
|
||||||
|
|
||||||
.. index:: single: trace function
|
.. index:: single: trace function
|
||||||
|
|
||||||
Set a trace function for all threads started from the :mod:`threading` module.
|
Set a trace function for all threads started from the :mod:`!threading` module.
|
||||||
The *func* will be passed to :func:`sys.settrace` for each thread, before its
|
The *func* will be passed to :func:`sys.settrace` for each thread, before its
|
||||||
:meth:`~Thread.run` method is called.
|
:meth:`~Thread.run` method is called.
|
||||||
|
|
||||||
.. function:: settrace_all_threads(func)
|
.. function:: settrace_all_threads(func)
|
||||||
|
|
||||||
Set a trace function for all threads started from the :mod:`threading` module
|
Set a trace function for all threads started from the :mod:`!threading` module
|
||||||
and all Python threads that are currently executing.
|
and all Python threads that are currently executing.
|
||||||
|
|
||||||
The *func* will be passed to :func:`sys.settrace` for each thread, before its
|
The *func* will be passed to :func:`sys.settrace` for each thread, before its
|
||||||
|
@ -186,13 +250,13 @@ This module defines the following functions:
|
||||||
|
|
||||||
.. index:: single: profile function
|
.. index:: single: profile function
|
||||||
|
|
||||||
Set a profile function for all threads started from the :mod:`threading` module.
|
Set a profile function for all threads started from the :mod:`!threading` module.
|
||||||
The *func* will be passed to :func:`sys.setprofile` for each thread, before its
|
The *func* will be passed to :func:`sys.setprofile` for each thread, before its
|
||||||
:meth:`~Thread.run` method is called.
|
:meth:`~Thread.run` method is called.
|
||||||
|
|
||||||
.. function:: setprofile_all_threads(func)
|
.. function:: setprofile_all_threads(func)
|
||||||
|
|
||||||
Set a profile function for all threads started from the :mod:`threading` module
|
Set a profile function for all threads started from the :mod:`!threading` module
|
||||||
and all Python threads that are currently executing.
|
and all Python threads that are currently executing.
|
||||||
|
|
||||||
The *func* will be passed to :func:`sys.setprofile` for each thread, before its
|
The *func* will be passed to :func:`sys.setprofile` for each thread, before its
|
||||||
|
@ -257,8 +321,8 @@ when implemented, are mapped to module-level functions.
|
||||||
All of the methods described below are executed atomically.
|
All of the methods described below are executed atomically.
|
||||||
|
|
||||||
|
|
||||||
Thread-Local Data
|
Thread-local data
|
||||||
-----------------
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Thread-local data is data whose values are thread specific. If you
|
Thread-local data is data whose values are thread specific. If you
|
||||||
have data that you want to be local to a thread, create a
|
have data that you want to be local to a thread, create a
|
||||||
|
@ -389,8 +453,8 @@ affects what we see::
|
||||||
|
|
||||||
.. _thread-objects:
|
.. _thread-objects:
|
||||||
|
|
||||||
Thread Objects
|
Thread objects
|
||||||
--------------
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
The :class:`Thread` class represents an activity that is run in a separate
|
The :class:`Thread` class represents an activity that is run in a separate
|
||||||
thread of control. There are two ways to specify the activity: by passing a
|
thread of control. There are two ways to specify the activity: by passing a
|
||||||
|
@ -645,8 +709,8 @@ since it is impossible to detect the termination of alien threads.
|
||||||
|
|
||||||
.. _lock-objects:
|
.. _lock-objects:
|
||||||
|
|
||||||
Lock Objects
|
Lock objects
|
||||||
------------
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
A primitive lock is a synchronization primitive that is not owned by a
|
A primitive lock is a synchronization primitive that is not owned by a
|
||||||
particular thread when locked. In Python, it is currently the lowest level
|
particular thread when locked. In Python, it is currently the lowest level
|
||||||
|
@ -738,8 +802,8 @@ All methods are executed atomically.
|
||||||
|
|
||||||
.. _rlock-objects:
|
.. _rlock-objects:
|
||||||
|
|
||||||
RLock Objects
|
RLock objects
|
||||||
-------------
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
A reentrant lock is a synchronization primitive that may be acquired multiple
|
A reentrant lock is a synchronization primitive that may be acquired multiple
|
||||||
times by the same thread. Internally, it uses the concepts of "owning thread"
|
times by the same thread. Internally, it uses the concepts of "owning thread"
|
||||||
|
@ -848,8 +912,8 @@ call release as many times the lock has been acquired can lead to deadlock.
|
||||||
|
|
||||||
.. _condition-objects:
|
.. _condition-objects:
|
||||||
|
|
||||||
Condition Objects
|
Condition objects
|
||||||
-----------------
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
A condition variable is always associated with some kind of lock; this can be
|
A condition variable is always associated with some kind of lock; this can be
|
||||||
passed in or one will be created by default. Passing one in is useful when
|
passed in or one will be created by default. Passing one in is useful when
|
||||||
|
@ -1026,8 +1090,8 @@ item to the buffer only needs to wake up one consumer thread.
|
||||||
|
|
||||||
.. _semaphore-objects:
|
.. _semaphore-objects:
|
||||||
|
|
||||||
Semaphore Objects
|
Semaphore objects
|
||||||
-----------------
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
This is one of the oldest synchronization primitives in the history of computer
|
This is one of the oldest synchronization primitives in the history of computer
|
||||||
science, invented by the early Dutch computer scientist Edsger W. Dijkstra (he
|
science, invented by the early Dutch computer scientist Edsger W. Dijkstra (he
|
||||||
|
@ -1107,7 +1171,7 @@ Semaphores also support the :ref:`context management protocol <with-locks>`.
|
||||||
|
|
||||||
.. _semaphore-examples:
|
.. _semaphore-examples:
|
||||||
|
|
||||||
:class:`Semaphore` Example
|
:class:`Semaphore` example
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Semaphores are often used to guard resources with limited capacity, for example,
|
Semaphores are often used to guard resources with limited capacity, for example,
|
||||||
|
@ -1135,8 +1199,8 @@ causes the semaphore to be released more than it's acquired will go undetected.
|
||||||
|
|
||||||
.. _event-objects:
|
.. _event-objects:
|
||||||
|
|
||||||
Event Objects
|
Event objects
|
||||||
-------------
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
This is one of the simplest mechanisms for communication between threads: one
|
This is one of the simplest mechanisms for communication between threads: one
|
||||||
thread signals an event and other threads wait for it.
|
thread signals an event and other threads wait for it.
|
||||||
|
@ -1192,8 +1256,8 @@ method. The :meth:`~Event.wait` method blocks until the flag is true.
|
||||||
|
|
||||||
.. _timer-objects:
|
.. _timer-objects:
|
||||||
|
|
||||||
Timer Objects
|
Timer objects
|
||||||
-------------
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
This class represents an action that should be run only after a certain amount
|
This class represents an action that should be run only after a certain amount
|
||||||
of time has passed --- a timer. :class:`Timer` is a subclass of :class:`Thread`
|
of time has passed --- a timer. :class:`Timer` is a subclass of :class:`Thread`
|
||||||
|
@ -1230,8 +1294,8 @@ For example::
|
||||||
only work if the timer is still in its waiting stage.
|
only work if the timer is still in its waiting stage.
|
||||||
|
|
||||||
|
|
||||||
Barrier Objects
|
Barrier objects
|
||||||
---------------
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue