Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9a2346d

Browse filesBrowse files
authored
gh-134381: Fix RuntimeError when starting not-yet started Thread after fork (gh-134514)
1 parent 05a19b5 commit 9a2346d
Copy full SHA for 9a2346d

File tree

Expand file treeCollapse file tree

3 files changed

+29
-0
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+29
-0
lines changed

‎Lib/test/_test_multiprocessing.py

Copy file name to clipboardExpand all lines: Lib/test/_test_multiprocessing.py
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6844,6 +6844,28 @@ def f(x): return x*x
68446844
self.assertEqual("332833500", out.decode('utf-8').strip())
68456845
self.assertFalse(err, msg=err.decode('utf-8'))
68466846

6847+
def test_forked_thread_not_started(self):
6848+
# gh-134381: Ensure that a thread that has not been started yet in
6849+
# the parent process can be started within a forked child process.
6850+
6851+
if multiprocessing.get_start_method() != "fork":
6852+
self.skipTest("fork specific test")
6853+
6854+
q = multiprocessing.Queue()
6855+
t = threading.Thread(target=lambda: q.put("done"), daemon=True)
6856+
6857+
def child():
6858+
t.start()
6859+
t.join()
6860+
6861+
p = multiprocessing.Process(target=child)
6862+
p.start()
6863+
p.join(support.SHORT_TIMEOUT)
6864+
6865+
self.assertEqual(p.exitcode, 0)
6866+
self.assertEqual(q.get_nowait(), "done")
6867+
close_queue(q)
6868+
68476869

68486870
#
68496871
# Mixins
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix :exc:`RuntimeError` when using a not-started :class:`threading.Thread` after calling :func:`os.fork`

‎Modules/_threadmodule.c

Copy file name to clipboardExpand all lines: Modules/_threadmodule.c
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,12 @@ _PyThread_AfterFork(struct _pythread_runtime_state *state)
296296
continue;
297297
}
298298

299+
// Keep handles for threads that have not been started yet. They are
300+
// safe to start in the child process.
301+
if (handle->state == THREAD_HANDLE_NOT_STARTED) {
302+
continue;
303+
}
304+
299305
// Mark all threads as done. Any attempts to join or detach the
300306
// underlying OS thread (if any) could crash. We are the only thread;
301307
// it's safe to set this non-atomically.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.