From b394f4be3414a7501da0bfcb4ab258282506d9b4 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Wed, 20 Nov 2024 05:34:40 +0400 Subject: [PATCH 01/19] Add introduction to docs for threading module --- Doc/library/threading.rst | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index d4b343db36efb3..77180f8eee60fc 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -8,6 +8,54 @@ -------------- +Introduction +------------ + +The :mod:`threading` module provides a way to run multiple threads (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 reading from or writing to files, or making network requests, +where much of the time is spent waiting for external resources. + +Unlike the :mod:`multiprocessing` module, which uses separate processes to +bypass the :term:`Global Interpreter Lock `, 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, threading remains a useful tool for +achieving concurrency in many scenarios. + +A typical use case for :mod:`threading` includes managing a pool of worker +threads that can process multiple tasks concurrently. This 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) + print(f"crawl ended for {link}") + + links = [ + "https://example.com", + "https://another-example.com", + "https://yet-another-example.com" + ] + + # 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) + t.start() + + # Wait for all threads to finish + for t in threads: + t.join() + This module constructs higher-level threading interfaces on top of the lower level :mod:`_thread` module. From 729b7d5e8cea8a45700364df531d44242f9e0c87 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sun, 12 Jan 2025 16:54:18 +0000 Subject: [PATCH 02/19] Update threading.rst Co-authored-by: Peter Bierma --- Doc/library/threading.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 77180f8eee60fc..cc8ffddc7a8dab 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -21,7 +21,7 @@ where much of the time is spent waiting for external resources. Unlike the :mod:`multiprocessing` module, which uses separate processes to bypass the :term:`Global Interpreter Lock `, 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 +share the same memory space. However, the :term:`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, threading remains a useful tool for achieving concurrency in many scenarios. From 49ad4ae3452ec3f27e476b509f8073eb33c127e4 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sun, 12 Jan 2025 16:54:34 +0000 Subject: [PATCH 03/19] Update threading.rst Co-authored-by: Peter Bierma --- Doc/library/threading.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index cc8ffddc7a8dab..31b6a1d5a287e4 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -23,7 +23,7 @@ bypass the :term:`Global Interpreter Lock `, the threading module operates within a single process, meaning that all threads share the same memory space. However, the :term:`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, threading remains a useful tool for +Python bytecode at a time. Despite this, threads remain a useful tool for achieving concurrency in many scenarios. A typical use case for :mod:`threading` includes managing a pool of worker From a66dcc7b2a9c212a8ba2b3bd4bce9231b4937951 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Mon, 13 Jan 2025 01:22:47 +0400 Subject: [PATCH 04/19] Update threading.rst --- Doc/library/threading.rst | 78 +++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 31b6a1d5a287e4..2fdc41eabb69e5 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -6,6 +6,45 @@ **Source code:** :source:`Lib/threading.py` +This module constructs higher-level threading interfaces on top of the lower +level :mod:`_thread` module. + +.. versionchanged:: 3.7 + This module used to be optional, it is now always available. + +.. seealso:: + + :class:`concurrent.futures.ThreadPoolExecutor` offers a higher level interface + to push tasks to a background thread without blocking execution of the + calling thread, while still being able to retrieve their results when needed. + + :mod:`queue` provides a thread-safe interface for exchanging data between + running threads. + + :mod:`asyncio` offers an alternative approach to achieving task level + concurrency without requiring the use of multiple operating system threads. + +.. note:: + + In the Python 2.x series, this module contained ``camelCase`` names + for some methods and functions. These are deprecated as of Python 3.10, + but they are still supported for compatibility with Python 2.5 and lower. + + +.. impl-detail:: + + In CPython, due to the :term:`Global Interpreter Lock + `, only one thread + can execute Python code at once (even though certain performance-oriented + libraries might overcome this limitation). + If you want your application to make better use of the computational + resources of multi-core machines, you are advised to use + :mod:`multiprocessing` or :class:`concurrent.futures.ProcessPoolExecutor`. + However, threading is still an appropriate model if you want to run + multiple I/O-bound tasks simultaneously. + +.. include:: ../includes/wasm-notavail.rst + -------------- Introduction @@ -56,45 +95,6 @@ creating and starting threads using :class:`~threading.Thread`:: for t in threads: t.join() -This module constructs higher-level threading interfaces on top of the lower -level :mod:`_thread` module. - -.. versionchanged:: 3.7 - This module used to be optional, it is now always available. - -.. seealso:: - - :class:`concurrent.futures.ThreadPoolExecutor` offers a higher level interface - to push tasks to a background thread without blocking execution of the - calling thread, while still being able to retrieve their results when needed. - - :mod:`queue` provides a thread-safe interface for exchanging data between - running threads. - - :mod:`asyncio` offers an alternative approach to achieving task level - concurrency without requiring the use of multiple operating system threads. - -.. note:: - - In the Python 2.x series, this module contained ``camelCase`` names - for some methods and functions. These are deprecated as of Python 3.10, - but they are still supported for compatibility with Python 2.5 and lower. - - -.. impl-detail:: - - In CPython, due to the :term:`Global Interpreter Lock - `, only one thread - can execute Python code at once (even though certain performance-oriented - libraries might overcome this limitation). - If you want your application to make better use of the computational - resources of multi-core machines, you are advised to use - :mod:`multiprocessing` or :class:`concurrent.futures.ProcessPoolExecutor`. - However, threading is still an appropriate model if you want to run - multiple I/O-bound tasks simultaneously. - -.. include:: ../includes/wasm-notavail.rst - This module defines the following functions: From 2911537d2b69b8b75b3097bec8168aef2facde36 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Mon, 13 Jan 2025 19:45:39 +0400 Subject: [PATCH 05/19] move line in threading.rst --- Doc/library/threading.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 2fdc41eabb69e5..5192dc2e3ac325 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -6,6 +6,8 @@ **Source code:** :source:`Lib/threading.py` +-------------- + This module constructs higher-level threading interfaces on top of the lower level :mod:`_thread` module. @@ -45,8 +47,6 @@ level :mod:`_thread` module. .. include:: ../includes/wasm-notavail.rst --------------- - Introduction ------------ From 409b4d9433fc11972e925445537ed2d3474d3a6b Mon Sep 17 00:00:00 2001 From: donBarbos Date: Mon, 3 Feb 2025 19:10:54 +0400 Subject: [PATCH 06/19] Mention free-threaded builds --- Doc/library/threading.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 5192dc2e3ac325..586bc85483cad2 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -65,6 +65,10 @@ 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. +*(Experimental free-threaded builds of CPython disable the :term:`GIL`, +enabling true parallel execution of threads, but this feature is still under +development.)* + A typical use case for :mod:`threading` includes managing a pool of worker threads that can process multiple tasks concurrently. This basic example of creating and starting threads using :class:`~threading.Thread`:: From 115e53052a61c3730c07bbcbbc3b635f5fc98538 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Mon, 3 Feb 2025 19:17:40 +0400 Subject: [PATCH 07/19] Correct term spelling --- Doc/library/threading.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 7d6104814af499..01c32e7c6a24a6 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -65,9 +65,8 @@ 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. -*(Experimental free-threaded builds of CPython disable the :term:`GIL`, -enabling true parallel execution of threads, but this feature is still under -development.)* +*(Experimental free-threaded builds of CPython disable the GIL, enabling true +parallel execution of threads, but this feature is still under development.)* A typical use case for :mod:`threading` includes managing a pool of worker threads that can process multiple tasks concurrently. This basic example of From dcfe23135c6a716b2e666348073236b14b6410d5 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Tue, 4 Feb 2025 06:59:00 +0000 Subject: [PATCH 08/19] Update Doc/library/threading.rst Co-authored-by: Peter Bierma --- Doc/library/threading.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 01c32e7c6a24a6..265c87376dee4b 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -54,7 +54,7 @@ The :mod:`threading` module provides a way to run multiple threads (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 reading from or writing to files, or making network requests, +I/O-bound, such as file operations or making network requests, where much of the time is spent waiting for external resources. Unlike the :mod:`multiprocessing` module, which uses separate processes to From 898f863731978cb1e46019ea4dfdb4bdb5f20bef Mon Sep 17 00:00:00 2001 From: donBarbos Date: Tue, 4 Feb 2025 06:59:23 +0000 Subject: [PATCH 09/19] Update Doc/library/threading.rst Co-authored-by: Peter Bierma --- Doc/library/threading.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 265c87376dee4b..4ee290be746a79 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -92,6 +92,9 @@ creating and starting threads using :class:`~threading.Thread`:: # 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 From ba7f6f6e98f721c03d53cdbd87648fab9119772e Mon Sep 17 00:00:00 2001 From: donBarbos Date: Tue, 4 Feb 2025 06:59:40 +0000 Subject: [PATCH 10/19] Update Doc/library/threading.rst Co-authored-by: Peter Bierma --- Doc/library/threading.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 4ee290be746a79..c9ee5b0d8da644 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -65,8 +65,7 @@ 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. -*(Experimental free-threaded builds of CPython disable the GIL, enabling true -parallel execution of threads, but this feature is still under development.)* +As of Python 3.13, experimental :term:`free-threaded ` builds can disable the GIL, enabling true parallel execution of threads, but this feature is not available by default. (See :pep:`703`.) A typical use case for :mod:`threading` includes managing a pool of worker threads that can process multiple tasks concurrently. This basic example of From 0f3d1e9787134914b28de8cb05bf03550d227486 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Tue, 4 Feb 2025 06:59:55 +0000 Subject: [PATCH 11/19] Update Doc/library/threading.rst Co-authored-by: Peter Bierma --- Doc/library/threading.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index c9ee5b0d8da644..40448777ac677d 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -76,7 +76,7 @@ creating and starting threads using :class:`~threading.Thread`:: def crawl(link, delay=3): print(f"crawl started for {link}") - time.sleep(delay) + time.sleep(delay) # Blocking I/O, simulating a network request print(f"crawl ended for {link}") links = [ From 39cad632557988e3bca4991ae72cd6e927d548c2 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Tue, 4 Feb 2025 07:00:07 +0000 Subject: [PATCH 12/19] Update Doc/library/threading.rst Co-authored-by: Peter Bierma --- Doc/library/threading.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 40448777ac677d..003b00cff47266 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -80,9 +80,9 @@ creating and starting threads using :class:`~threading.Thread`:: print(f"crawl ended for {link}") links = [ - "https://example.com", - "https://another-example.com", - "https://yet-another-example.com" + "https://python.org", + "https://docs.python.org", + "https://peps.python.org" ] # Start threads for each link From 70986a09da40f38e6138ed3955fd3c27a597f8f0 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Tue, 4 Feb 2025 11:16:03 +0400 Subject: [PATCH 13/19] Add section --- Doc/library/threading.rst | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 003b00cff47266..6382fc0123081f 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -57,16 +57,6 @@ 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. -Unlike the :mod:`multiprocessing` module, which uses separate processes to -bypass the :term:`Global Interpreter Lock `, the -threading module operates within a single process, meaning that all threads -share the same memory space. However, the :term:`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 ` builds can disable the GIL, enabling true parallel execution of threads, but this feature is not available by default. (See :pep:`703`.) - A typical use case for :mod:`threading` includes managing a pool of worker threads that can process multiple tasks concurrently. This basic example of creating and starting threads using :class:`~threading.Thread`:: @@ -100,6 +90,21 @@ creating and starting threads using :class:`~threading.Thread`:: for t in threads: t.join() +GIL and Performance Considerations +---------------------------------- + +Unlike the :mod:`multiprocessing` module, which uses separate processes to +bypass the :term:`Global Interpreter Lock `, the +threading module operates within a single process, meaning that all threads +share the same memory space. However, the :term:`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 ` builds +can disable the :term:`GIL`, enabling true parallel execution of threads, but +this feature is not available by default. (See :pep:`703`.) + This module defines the following functions: From 4f0c60dc1aa14cf609ea65a7a8a64f84407f163d Mon Sep 17 00:00:00 2001 From: Semyon Moroz Date: Sat, 29 Mar 2025 10:39:53 +0000 Subject: [PATCH 14/19] Update Doc/library/threading.rst Co-authored-by: Peter Bierma --- Doc/library/threading.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 6382fc0123081f..0ca54d9e8bbeb9 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -58,7 +58,7 @@ 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. This basic example of +threads that can process multiple tasks concurrently. Here's a basic example of creating and starting threads using :class:`~threading.Thread`:: import threading From 82b22c75df590b7d7482c92b3416d2686ab5a751 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sat, 29 Mar 2025 14:50:16 +0400 Subject: [PATCH 15/19] Add wikipedia page as reference --- Doc/library/threading.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 0ca54d9e8bbeb9..42f85f1a90ac93 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -50,7 +50,8 @@ level :mod:`_thread` module. Introduction ------------ -The :mod:`threading` module provides a way to run multiple threads (smaller +The :mod:`threading` module provides a way to run multiple `threads +`_ (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 From e2dd4f62229ccfc9cecb8e82725444de35bb0fc1 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Thu, 1 May 2025 23:02:06 +0400 Subject: [PATCH 16/19] Reorganize structure --- Doc/library/threading.rst | 89 ++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 42f85f1a90ac93..b574c48c9c0a18 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -11,40 +11,6 @@ This module constructs higher-level threading interfaces on top of the lower level :mod:`_thread` module. -.. versionchanged:: 3.7 - This module used to be optional, it is now always available. - -.. seealso:: - - :class:`concurrent.futures.ThreadPoolExecutor` offers a higher level interface - to push tasks to a background thread without blocking execution of the - calling thread, while still being able to retrieve their results when needed. - - :mod:`queue` provides a thread-safe interface for exchanging data between - running threads. - - :mod:`asyncio` offers an alternative approach to achieving task level - concurrency without requiring the use of multiple operating system threads. - -.. note:: - - In the Python 2.x series, this module contained ``camelCase`` names - for some methods and functions. These are deprecated as of Python 3.10, - but they are still supported for compatibility with Python 2.5 and lower. - - -.. impl-detail:: - - In CPython, due to the :term:`Global Interpreter Lock - `, only one thread - can execute Python code at once (even though certain performance-oriented - libraries might overcome this limitation). - If you want your application to make better use of the computational - resources of multi-core machines, you are advised to use - :mod:`multiprocessing` or :class:`concurrent.futures.ProcessPoolExecutor`. - However, threading is still an appropriate model if you want to run - multiple I/O-bound tasks simultaneously. - .. include:: ../includes/wasm-notavail.rst Introduction @@ -91,6 +57,40 @@ creating and starting threads using :class:`~threading.Thread`:: for t in threads: t.join() +.. versionchanged:: 3.7 + This module used to be optional, it is now always available. + +.. seealso:: + + :class:`concurrent.futures.ThreadPoolExecutor` offers a higher level interface + to push tasks to a background thread without blocking execution of the + calling thread, while still being able to retrieve their results when needed. + + :mod:`queue` provides a thread-safe interface for exchanging data between + running threads. + + :mod:`asyncio` offers an alternative approach to achieving task level + concurrency without requiring the use of multiple operating system threads. + +.. note:: + + In the Python 2.x series, this module contained ``camelCase`` names + for some methods and functions. These are deprecated as of Python 3.10, + but they are still supported for compatibility with Python 2.5 and lower. + + +.. impl-detail:: + + In CPython, due to the :term:`Global Interpreter Lock + `, only one thread + can execute Python code at once (even though certain performance-oriented + libraries might overcome this limitation). + If you want your application to make better use of the computational + resources of multi-core machines, you are advised to use + :mod:`multiprocessing` or :class:`concurrent.futures.ProcessPoolExecutor`. + However, threading is still an appropriate model if you want to run + multiple I/O-bound tasks simultaneously. + GIL and Performance Considerations ---------------------------------- @@ -106,6 +106,9 @@ As of Python 3.13, experimental :term:`free-threaded ` builds can disable the :term:`GIL`, enabling true parallel execution of threads, but this feature is not available by default. (See :pep:`703`.) +Reference +--------- + This module defines the following functions: @@ -317,7 +320,7 @@ All of the methods described below are executed atomically. Thread-Local Data ------------------ +^^^^^^^^^^^^^^^^^ Thread-local data is data whose values are thread specific. To manage thread-local data, just create an instance of :class:`local` (or a @@ -340,7 +343,7 @@ The instance's values will be different for separate threads. .. _thread-objects: Thread Objects --------------- +^^^^^^^^^^^^^^ 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 @@ -575,7 +578,7 @@ since it is impossible to detect the termination of alien threads. .. _lock-objects: Lock Objects ------------- +^^^^^^^^^^^^ 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 @@ -668,7 +671,7 @@ All methods are executed atomically. .. _rlock-objects: RLock Objects -------------- +^^^^^^^^^^^^^ 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" @@ -771,7 +774,7 @@ call release as many times the lock has been acquired can lead to deadlock. .. _condition-objects: Condition Objects ------------------ +^^^^^^^^^^^^^^^^^ 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 @@ -943,7 +946,7 @@ item to the buffer only needs to wake up one consumer thread. .. _semaphore-objects: Semaphore Objects ------------------ +^^^^^^^^^^^^^^^^^ 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 @@ -1052,7 +1055,7 @@ causes the semaphore to be released more than it's acquired will go undetected. .. _event-objects: Event Objects -------------- +^^^^^^^^^^^^^ This is one of the simplest mechanisms for communication between threads: one thread signals an event and other threads wait for it. @@ -1109,7 +1112,7 @@ method. The :meth:`~Event.wait` method blocks until the flag is true. .. _timer-objects: Timer Objects -------------- +^^^^^^^^^^^^^ 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` @@ -1147,7 +1150,7 @@ For example:: Barrier Objects ---------------- +^^^^^^^^^^^^^^^ .. versionadded:: 3.2 From 7bf0de478f4a81f75d08f73962fe6d184ab09fc4 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Thu, 1 May 2025 23:14:18 +0400 Subject: [PATCH 17/19] Add comma for last list item in code example --- Doc/library/threading.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index b574c48c9c0a18..4635477bfa1d6e 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -33,13 +33,13 @@ creating and starting threads using :class:`~threading.Thread`:: def crawl(link, delay=3): print(f"crawl started for {link}") - time.sleep(delay) # Blocking I/O, simulating a network request + 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" + "https://peps.python.org", ] # Start threads for each link From 5ecbb722f6c7211c948c4ea0148172ae5b452603 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Thu, 1 May 2025 23:17:38 +0400 Subject: [PATCH 18/19] Correct indents --- Doc/library/threading.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 4635477bfa1d6e..1d1d9cd5c24b3a 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -49,8 +49,8 @@ creating and starting threads using :class:`~threading.Thread`:: t = threading.Thread(target=crawl, args=(link,), kwargs={"delay": 2}) threads.append(t) - # Start each thread - for t in threads: + # Start each thread + for t in threads: t.start() # Wait for all threads to finish From 0d3c734b29c3a77d5a5c50f08d6dbbe5bfb6cf07 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sun, 11 May 2025 07:05:32 +0400 Subject: [PATCH 19/19] Accept suggestions --- Doc/library/threading.rst | 56 ++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 1d1d9cd5c24b3a..fffa142f19dffc 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -16,15 +16,15 @@ level :mod:`_thread` module. Introduction ------------ -The :mod:`threading` module provides a way to run multiple `threads +The :mod:`!threading` module provides a way to run multiple `threads `_ (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, +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 +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`:: @@ -91,20 +91,22 @@ creating and starting threads using :class:`~threading.Thread`:: However, threading is still an appropriate model if you want to run multiple I/O-bound tasks simultaneously. -GIL and Performance Considerations +GIL and performance considerations ---------------------------------- Unlike the :mod:`multiprocessing` module, which uses separate processes to -bypass the :term:`Global Interpreter Lock `, the -threading module operates within a single process, meaning that all threads -share the same memory space. However, the :term:`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. +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 ` builds -can disable the :term:`GIL`, enabling true parallel execution of threads, but -this feature is not available by default. (See :pep:`703`.) +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 --------- @@ -124,7 +126,7 @@ This module defines the following functions: 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 - :mod:`threading` module, a dummy thread object with limited functionality is + :mod:`!threading` module, a dummy thread object with limited functionality is returned. The function ``currentThread`` is a deprecated alias for this function. @@ -219,13 +221,13 @@ This module defines the following functions: .. 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 :meth:`~Thread.run` method is called. .. 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. The *func* will be passed to :func:`sys.settrace` for each thread, before its @@ -248,13 +250,13 @@ This module defines the following functions: .. 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 :meth:`~Thread.run` method is called. .. 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. The *func* will be passed to :func:`sys.setprofile` for each thread, before its @@ -319,7 +321,7 @@ when implemented, are mapped to module-level functions. 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. To manage @@ -342,7 +344,7 @@ The instance's values will be different for separate threads. .. _thread-objects: -Thread Objects +Thread objects ^^^^^^^^^^^^^^ The :class:`Thread` class represents an activity that is run in a separate @@ -577,7 +579,7 @@ since it is impossible to detect the termination of alien threads. .. _lock-objects: -Lock Objects +Lock objects ^^^^^^^^^^^^ A primitive lock is a synchronization primitive that is not owned by a @@ -670,7 +672,7 @@ All methods are executed atomically. .. _rlock-objects: -RLock Objects +RLock objects ^^^^^^^^^^^^^ A reentrant lock is a synchronization primitive that may be acquired multiple @@ -773,7 +775,7 @@ call release as many times the lock has been acquired can lead to deadlock. .. _condition-objects: -Condition Objects +Condition objects ^^^^^^^^^^^^^^^^^ A condition variable is always associated with some kind of lock; this can be @@ -945,7 +947,7 @@ item to the buffer only needs to wake up one consumer thread. .. _semaphore-objects: -Semaphore Objects +Semaphore objects ^^^^^^^^^^^^^^^^^ This is one of the oldest synchronization primitives in the history of computer @@ -1026,7 +1028,7 @@ Semaphores also support the :ref:`context management protocol `. .. _semaphore-examples: -:class:`Semaphore` Example +:class:`Semaphore` example ^^^^^^^^^^^^^^^^^^^^^^^^^^ Semaphores are often used to guard resources with limited capacity, for example, @@ -1054,7 +1056,7 @@ causes the semaphore to be released more than it's acquired will go undetected. .. _event-objects: -Event Objects +Event objects ^^^^^^^^^^^^^ This is one of the simplest mechanisms for communication between threads: one @@ -1111,7 +1113,7 @@ method. The :meth:`~Event.wait` method blocks until the flag is true. .. _timer-objects: -Timer Objects +Timer objects ^^^^^^^^^^^^^ This class represents an action that should be run only after a certain amount @@ -1149,7 +1151,7 @@ For example:: only work if the timer is still in its waiting stage. -Barrier Objects +Barrier objects ^^^^^^^^^^^^^^^ .. versionadded:: 3.2