summaryrefslogtreecommitdiffstats
path: root/Lib/threading.py
Commit message (Collapse)AuthorAgeFilesLines
* gh-59705: Set OS thread name when Thread.name is changed (#127702)Victor Stinner2024-12-101-5/+11
| | | Co-authored-by: Petr Viktorin <encukou@gmail.com>
* gh-59705: Add _thread.set_name() function (#127338)Victor Stinner2024-12-061-0/+9
| | | | | | | | | | | On Linux, threading.Thread now sets the thread name to the operating system. * configure now checks if pthread_getname_np() and pthread_setname_np() functions are available. * Add PYTHREAD_NAME_MAXLEN macro. * Add _thread._NAME_MAXLEN constant for test_threading. Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
* gh-121474: Add threading.Barrier parties arg sanity check. (GH-121480)Clinton2024-07-301-0/+2
|
* gh-121905: Consistently use "floating-point" instead of "floating point" ↵Serhiy Storchaka2024-07-191-3/+3
| | | | (GH-121907)
* gh-114271: Fix race in `Thread.join()` (#114839)mpage2024-03-161-186/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There is a race between when `Thread._tstate_lock` is released[^1] in `Thread._wait_for_tstate_lock()` and when `Thread._stop()` asserts[^2] that it is unlocked. Consider the following execution involving threads A, B, and C: 1. A starts. 2. B joins A, blocking on its `_tstate_lock`. 3. C joins A, blocking on its `_tstate_lock`. 4. A finishes and releases its `_tstate_lock`. 5. B acquires A's `_tstate_lock` in `_wait_for_tstate_lock()`, releases it, but is swapped out before calling `_stop()`. 6. C is scheduled, acquires A's `_tstate_lock` in `_wait_for_tstate_lock()` but is swapped out before releasing it. 7. B is scheduled, calls `_stop()`, which asserts that A's `_tstate_lock` is not held. However, C holds it, so the assertion fails. The race can be reproduced[^3] by inserting sleeps at the appropriate points in the threading code. To do so, run the `repro_join_race.py` from the linked repo. There are two main parts to this PR: 1. `_tstate_lock` is replaced with an event that is attached to `PyThreadState`. The event is set by the runtime prior to the thread being cleared (in the same place that `_tstate_lock` was released). `Thread.join()` blocks waiting for the event to be set. 2. `_PyInterpreterState_WaitForThreads()` provides the ability to wait for all non-daemon threads to exit. To do so, an `is_daemon` predicate was added to `PyThreadState`. This field is set each time a thread is created. `threading._shutdown()` now calls into `_PyInterpreterState_WaitForThreads()` instead of waiting on `_tstate_lock`s. [^1]: https://github.com/python/cpython/blob/441affc9e7f419ef0b68f734505fa2f79fe653c7/Lib/threading.py#L1201 [^2]: https://github.com/python/cpython/blob/441affc9e7f419ef0b68f734505fa2f79fe653c7/Lib/threading.py#L1115 [^3]: https://github.com/mpage/cpython/commit/81946532792f938cd6f6ab4c4ff92a4edf61314f --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Antoine Pitrou <antoine@python.org>
* gh-114271: Make `_thread.ThreadHandle` thread-safe in free-threaded builds ↵mpage2024-03-011-17/+7
| | | | | | | | | | | | | | | | | (GH-115190) Make `_thread.ThreadHandle` thread-safe in free-threaded builds We protect the mutable state of `ThreadHandle` using a `_PyOnceFlag`. Concurrent operations (i.e. `join` or `detach`) on `ThreadHandle` block until it is their turn to execute or an earlier operation succeeds. Once an operation has been applied successfully all future operations complete immediately. The `join()` method is now idempotent. It may be called multiple times but the underlying OS thread will only be joined once. After `join()` succeeds, any future calls to `join()` will succeed immediately. The internal thread handle `detach()` method has been removed.
* gh-115035: Mark ThreadHandles as non-joinable earlier after forking (#115042)Sam Gross2024-02-061-4/+1
| | | | | | This marks dead ThreadHandles as non-joinable earlier in `PyOS_AfterFork_Child()` before we execute any Python code. The handles are stored in a global linked list in `_PyRuntimeState` because `fork()` affects the entire process.
* gh-109653: Speedup import of threading module (#114509)Daniel Hollas2024-01-311-3/+1
| | | | | Avoiding an import of functools leads to 50% speedup of import time. Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
* gh-114315: Make `threading.Lock` a real class, not a factory function (#114479)Nikita Sobolev2024-01-251-2/+2
| | | | | | | | | | `threading.Lock` is now the underlying class and is constructable rather than the old factory function. This allows for type annotations to refer to it which had no non-ugly way to be expressed prior to this. --------- Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: Gregory P. Smith <greg@krypto.org>
* gh-114423: Remove DummyThread from threading._active when thread dies ↵Fabio Zadrozny2024-01-231-11/+37
| | | | (GH-114424)
* gh-102512: Turn _DummyThread into _MainThread after os.fork() called from a ↵Serhiy Storchaka2024-01-221-1/+8
| | | | | | | | | | | | | | | | | foreign thread (GH-113261) Always set a _MainThread as a main thread after os.fork() is called from a thread started not by the threading module. A new _MainThread was already set as a new main thread after fork if threading.current_thread() was not called for a foreign thread before fork. Now, if it was called before fork, the implicitly created _DummyThread will be turned into _MainThread after fork. It fixes, in particularly, an incompatibility of _DummyThread with the threading shutdown logic which relies on the main thread having tstate_lock. Co-authored-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
* GH-110829: Ensure Thread.join() joins the OS thread (#110848)Antoine Pitrou2023-11-041-15/+48
| | | | | | | Joining a thread now ensures the underlying OS thread has exited. This is required for safer fork() in multi-threaded processes. --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
* gh-109860: Use a New Thread State When Switching Interpreters, When ↵Eric Snow2023-10-031-2/+5
| | | | | | | | | Necessary (gh-110245) In a few places we switch to another interpreter without knowing if it has a thread state associated with the current thread. For the main interpreter there wasn't much of a problem, but for subinterpreters we were *mostly* okay re-using the tstate created with the interpreter (located via PyInterpreterState_ThreadHead()). There was a good chance that tstate wasn't actually in use by another thread. However, there are no guarantees of that. Furthermore, re-using an already used tstate is currently fragile. To address this, now we create a new thread state in each of those places and use it. One consequence of this change is that PyInterpreterState_ThreadHead() may not return NULL (though that won't happen for the main interpreter).
* gh-105716: Support Background Threads in Subinterpreters Consistently ↵Eric Snow2023-10-021-1/+3
| | | | | | | (gh-109921) The existence of background threads running on a subinterpreter was preventing interpreters from getting properly destroyed, as well as impacting the ability to run the interpreter again. It also affected how we wait for non-daemon threads to finish. We add PyInterpreterState.threads.main, with some internal C-API functions.
* gh-109593: Fix reentrancy issue in multiprocessing resource_tracker (#109629)Antoine Pitrou2023-09-261-0/+7
| | | | | --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
* gh-102029: Deprecate passing arguments to `_PyRLock` in `threading` (#102071)Nikita Sobolev2023-08-171-0/+7
|
* gh-106236: Replace `assert` with `raise RuntimeError` in `threading.py` ↵Nikita Sobolev2023-07-121-3/+4
| | | | | (#106237) Replace `assert` with `raise ` in `threading.py` so that -OO does not alter _DummyThread behavior.
* gh-104837: Revert "gh-104341: Add a Separate "Running" Lock for Each Thread ↵Gregory P. Smith2023-05-241-41/+29
| | | | | | | (gh-104754) (#104838) gh-104837: Revert "gh-104341: Add a Separate "Running" Lock for Each Thread (gh-104754)" This reverts commit 097b7830cd67f039ff36ba4fa285d82d26e25e84.
* gh-104341: Add a Separate "Running" Lock for Each Thread (gh-104754)Eric Snow2023-05-231-29/+41
| | | | | Having a separate lock means Thread.join() doesn't need to wait for the thread to be cleaned up first. It can wait for the thread's Python target to finish running. This gives us some flexibility in how we clean up threads. (This is a minor cleanup as part of a fix for gh-104341.)
* gh-100228: Warn from os.fork() if other threads exist. (#100229)Gregory P. Smith2022-12-291-0/+2
| | | | | Not comprehensive, best effort warning. There are cases when threads exist on some platforms that this code cannot detect. macOS when API permissions allow and Linux with a readable /proc procfs present are the currently supported cases where a warning should show up reliably. Starting with a DeprecationWarning for now, it is less disruptive than something like RuntimeWarning and most likely to only be seen in people's CI tests - a good place to start with this messaging.
* gh-98610: Adjust the Optional Restrictions on Subinterpreters (GH-98618)Eric Snow2022-10-311-1/+7
| | | | | | | Previously, the optional restrictions on subinterpreters were: disallow fork, subprocess, and threads. By default, we were disallowing all three for "isolated" interpreters. We always allowed all three for the main interpreter and those created through the legacy `Py_NewInterpreter()` API. Those settings were a bit conservative, so here we've adjusted the optional restrictions to: fork, exec, threads, and daemon threads. The default for "isolated" interpreters disables fork, exec, and daemon threads. Regular threads are allowed by default. We continue always allowing everything For the main interpreter and the legacy API. In the code, we add `_PyInterpreterConfig.allow_exec` and `_PyInterpreterConfig.allow_daemon_threads`. We also add `Py_RTFLAGS_DAEMON_THREADS` and `Py_RTFLAGS_EXEC`.
* gh-96349: fix minor performance regression initializing threading.Event ↵Daniel Giger2022-08-301-9/+3
| | | | (gh-96350)
* fix threading.Event.isSet() docstring (#96297)Daniel Giger2022-08-271-1/+1
| | | fixes gh-96296
* GH-93503: Add thread-specific APIs to set profiling and tracing functions in ↵Pablo Galindo Salgado2022-08-241-3/+22
| | | | | | | | | | | | | | | | | the C-API (#93504) * gh-93503: Add APIs to set profiling and tracing functions in all threads in the C-API * Use a separate API * Fix NEWS entry * Add locks around the loop * Document ignoring exceptions * Use the new APIs in the sys module * Update docs
* gh-84623: Remove unused imports in stdlib (#93773)Victor Stinner2022-06-131-1/+1
|
* gh-92530: Fix an issue that occurred after interrupting ↵Serhiy Storchaka2022-05-161-7/+14
| | | | | | | | threading.Condition.notify (GH-92534) If Condition.notify() was interrupted just after it released the waiter lock, but before removing it from the queue, the following calls of notify() failed with RuntimeError: cannot release un-acquired lock.
* gh-89474: Improve Semaphore/BoundedSemaphore.release() for multiple thread ↵Dong-hee Na2022-05-081-5/+3
| | | | waiting (GH-92447)
* bpo-45735: Promise the long-time truth that `args=list` works (GH-30982)Charlie Zhao2022-02-261-1/+1
| | | | | | For threads, and for multiprocessing, it's always been the case that ``args=list`` works fine when passed to ``Process()`` or ``Thread()``, and such code is common in the wild. But, according to the docs, only a tuple can be used. This brings the docs into synch with reality. Doc changes by Charlie Zhao. Co-authored-by: Tim Peters <tim.peters@gmail.com>
* Fix typos in the Lib directory (GH-28775)Christian Clauss2021-10-061-1/+1
| | | | | Fix typos in the Lib directory as identified by codespell. Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
* [typo] Fix threading.Barrier comment that used confusing punctuation (GH-28623)Łukasz Langa2021-09-291-1/+1
| | | | | Removed extra comma in comment that indicates state of a `Barrier` as it was confusing and breaking the flow while reading. Co-authored-by: Priyank <5903604+cpriyank@users.noreply.github.com>
* bpo-24391: Better reprs for threading objects. (GH-20534)Serhiy Storchaka2021-09-291-0/+22
| | | | Add reprs for Semaphore, BoundedSemaphore, Event, and Barrier.
* bpo-1596321: Fix threading._shutdown() for the main thread (GH-28549)Victor Stinner2021-09-271-8/+17
| | | | | Fix the threading._shutdown() function when the threading module was imported first from a thread different than the main thread: no longer log an error at Python exit.
* bpo-45274: Fix Thread._wait_for_tstate_lock() race condition (GH-28532)Victor Stinner2021-09-271-4/+17
| | | | | | Fix a race condition in the Thread.join() method of the threading module. If the function is interrupted by a signal and the signal handler raises an exception, make sure that the thread remains in a consistent state to prevent a deadlock.
* bpo-44422: threading.Thread reuses the _delete() method (GH-26741)Victor Stinner2021-06-161-7/+1
| | | | | | | The _bootstrap_inner() method of threading.Thread now reuses its _delete() method rather than accessing _active() directly. It became possible since _active_limbo_lock became reentrant. Moreover, it no longer ignores any exception when deleting the thread from the _active dictionary.
* bpo-44422: Fix threading.enumerate() reentrant call (GH-26727)Victor Stinner2021-06-151-3/+6
| | | | The threading.enumerate() function now uses a reentrant lock to prevent a hang on reentrant call.
* bpo-37788: Fix reference leak when Thread is never joined (GH-26103)Antoine Pitrou2021-05-141-1/+18
| | | When a Thread is not joined after it has stopped, its lock may remain in the _shutdown_locks set until interpreter shutdown. If many threads are created this way, the _shutdown_locks set could therefore grow endlessly. To avoid such a situation, purge expired locks each time a new one is added or removed.
* bpo-25821: Fix inaccuracy in threading.enumerate/is_alive documentation (#23192)Irit Katriel2021-05-111-2/+2
|
* bpo-43723: Deprecate camelCase aliases from threading (GH-25174)Jelle Zijlstra2021-04-121-4/+72
| | | | | | The snake_case names have existed since Python 2.6, so there is no reason to keep the old camelCase names around. One similar method, threading.Thread.isAlive, was already removed in Python 3.9 (bpo-37804).
* bpo-41149: Fix a bug in threading that causes fals-y threads callables to ↵BarneyStratford2021-02-021-1/+1
| | | | fail to start. (GH-21201)
* bpo-42350: Fix Thread._reset_internal_locks() (GH-23268)Victor Stinner2020-11-161-2/+6
| | | | | Fix the threading.Thread class at fork: do nothing if the thread is already stopped (ex: fork called at Python exit). Previously, an error was logged in the child process.
* bpo-42308: Add threading.__excepthook__ (GH-23218)Mario Corchero2020-11-121-0/+4
| | | | | Add threading.__excepthook__ to allow retrieving the original value of threading.excepthook in case it is set to a broken or a different value.
* bpo-42251: Add gettrace and getprofile to threading (GH-23125)Mario Corchero2020-11-041-1/+9
| | | This allows to retrieve the functions that were set in these two, which might differ from sys.gettrace and sys.getprofile within a thread.
* bpo-41833: threading.Thread now uses the target name (GH-22357)Victor Stinner2020-09-231-5/+15
|
* bpo-40234: Revert "bpo-37266: Daemon threads are now denied in ↵Victor Stinner2020-04-121-5/+0
| | | | | subinterpreters (GH-14049)" (GH-19456) This reverts commit 066e5b1a917ec2134e8997d2cadd815724314252.
* bpo-40089: Add _at_fork_reinit() method to locks (GH-19195)Victor Stinner2020-04-071-5/+15
| | | | | | | | | | | | | | | Add a private _at_fork_reinit() method to _thread.Lock, _thread.RLock, threading.RLock and threading.Condition classes: reinitialize the lock after fork in the child process; reset the lock to the unlocked state. Rename also the private _reset_internal_locks() method of threading.Event to _at_fork_reinit(). * Add _PyThread_at_fork_reinit() private function. It is excluded from the limited C API. * threading.Thread._reset_internal_locks() now calls _at_fork_reinit() on self._tstate_lock rather than creating a new Python lock object.
* bpo-39812: Remove daemon threads in concurrent.futures (GH-19149)Kyle Stanley2020-03-271-0/+29
| | | | | | Remove daemon threads from :mod:`concurrent.futures` by adding an internal `threading._register_atexit()`, which calls registered functions prior to joining all non-daemon threads. This allows for compatibility with subinterpreters, which don't support daemon threads.
* bpo-40089: Fix threading._after_fork() (GH-19191)Victor Stinner2020-03-271-1/+9
| | | | | If fork was not called by a thread spawned by threading.Thread, threading._after_fork() now creates a _MainThread instance for _main_thread, instead of a _DummyThread instance.
* bpo-15999: Clean up of handling boolean arguments. (GH-15610)Serhiy Storchaka2019-09-011-1/+1
| | | | | | * Use the 'p' format unit instead of manually called PyObject_IsTrue(). * Pass boolean value instead 0/1 integers to functions that needs boolean. * Convert some arguments to boolean only once.
* bpo-10978: Semaphores can release multiple threads at a time (GH-15588)Raymond Hettinger2019-08-291-9/+15
|
* Revert "bpo-37788: Fix a reference leak if a thread is not joined ↵Victor Stinner2019-08-191-10/+0
| | | | | (GH-15228)" (GH-15338) This reverts commit d3dcc92778807ae8f7ebe85178f36a29711cd478.