diff options
author | Sam Gross <colesbury@gmail.com> | 2024-03-19 14:40:20 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-19 14:40:20 -0400 |
commit | 60e105c1c11ecca1680d03c38aa06bcc77a28714 (patch) | |
tree | ec314b15b7739ae1f0c463ebd47cff1d06b4260e /Lib/test/test_threading.py | |
parent | 025ef7a5f7b424fba8713e448244b952bf897df3 (diff) | |
download | cpython-60e105c1c11ecca1680d03c38aa06bcc77a28714.tar.gz cpython-60e105c1c11ecca1680d03c38aa06bcc77a28714.zip |
gh-113964: Don't prevent new threads until all non-daemon threads exit (#116677)
Starting in Python 3.12, we prevented calling fork() and starting new threads
during interpreter finalization (shutdown). This has led to a number of
regressions and flaky tests. We should not prevent starting new threads
(or `fork()`) until all non-daemon threads exit and finalization starts in
earnest.
This changes the checks to use `_PyInterpreterState_GetFinalizing(interp)`,
which is set immediately before terminating non-daemon threads.
Diffstat (limited to 'Lib/test/test_threading.py')
-rw-r--r-- | Lib/test/test_threading.py | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index f1dc12944cb..4414d2bb9cd 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -1154,21 +1154,21 @@ class ThreadTests(BaseTestCase): self.assertEqual(out, b'') self.assertEqual(err, b'') - def test_start_new_thread_at_exit(self): + def test_start_new_thread_at_finalization(self): code = """if 1: - import atexit import _thread def f(): print("shouldn't be printed") - def exit_handler(): - _thread.start_new_thread(f, ()) - - atexit.register(exit_handler) + class AtFinalization: + def __del__(self): + print("OK") + _thread.start_new_thread(f, ()) + at_finalization = AtFinalization() """ _, out, err = assert_python_ok("-c", code) - self.assertEqual(out, b'') + self.assertEqual(out.strip(), b"OK") self.assertIn(b"can't create new thread at interpreter shutdown", err) class ThreadJoinOnShutdown(BaseTestCase): @@ -1297,6 +1297,30 @@ class ThreadJoinOnShutdown(BaseTestCase): rc, out, err = assert_python_ok('-c', script) self.assertFalse(err) + def test_thread_from_thread(self): + script = """if True: + import threading + import time + + def thread2(): + time.sleep(0.05) + print("OK") + + def thread1(): + time.sleep(0.05) + t2 = threading.Thread(target=thread2) + t2.start() + + t = threading.Thread(target=thread1) + t.start() + # do not join() -- the interpreter waits for non-daemon threads to + # finish. + """ + rc, out, err = assert_python_ok('-c', script) + self.assertEqual(err, b"") + self.assertEqual(out.strip(), b"OK") + self.assertEqual(rc, 0) + @skip_unless_reliable_fork def test_reinit_tls_after_fork(self): # Issue #13817: fork() would deadlock in a multithreaded program with |