aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_threading.py
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-03-19 14:40:20 -0400
committerGitHub <noreply@github.com>2024-03-19 14:40:20 -0400
commit60e105c1c11ecca1680d03c38aa06bcc77a28714 (patch)
treeec314b15b7739ae1f0c463ebd47cff1d06b4260e /Lib/test/test_threading.py
parent025ef7a5f7b424fba8713e448244b952bf897df3 (diff)
downloadcpython-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.py38
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