Skip to content

Conversation

@gpshead
Copy link
Member

@gpshead gpshead commented Nov 12, 2025

This splits the OS API specific functionality to get the number of threads out from the fallback Python method and warning raising code itself. This way the OS APIs can be queried before we've run
os.register_at_fork(after_in_parent=...) registered functions which themselves may (re)start threads that would otherwise be detected.

This is best effort. If the OS APIs are either unavailable or fail, the warning generating code still falls back to looking at the Python threading state after the CPython interpreter world has been restarted and the after_in_parent calls have been made. The common case for most Linux and macOS environments should work today.

This also lines up with the existing TODO refactoring, we may choose to expose this API to get the number of OS threads in the os module in the future.

This splits the OS API specific functionality to get the number of threads out
from the fallback Python method and warning raising code itself.  This way the
OS APIs can be queried before we've run
`os.register_at_fork(after_in_parent=...)` registered functions which
themselves may (re)start threads that would otherwise be detected.

This is best effort.  If the OS APIs are either unavailable or fail, the
warning generating code still falls back to looking at the Python threading
state after the CPython interpreter world has been restarted and the
after_in_parent calls have been made.  The common case for most Linux and macOS
environments should work today.

This also lines up with the existing TODO refactoring, we may choose to expose
this API to get the number of OS threads in the `os` module in the future.
@gpshead gpshead self-assigned this Nov 12, 2025
@gpshead gpshead added OS-mac stdlib Standard Library Python modules in the Lib/ directory extension-modules C modules in the Modules dir OS-freebsd OS-linux OS-netbsd labels Nov 12, 2025
Comment on lines +8631 to +8632
// Called before AfterFork_Parent in case those hooks start threads.
Py_ssize_t num_os_threads = get_number_of_os_threads();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other comment on the issue was if we should make this call right after BeforeFork but before the fork call itself. I don't think it makes a lot of difference. This in theory is slightly faster as it runs in parallel with the new child, but might have the downside that actual posix pthread_atfork C library call users could have their own parent callback start a thread from C which we're still missing?

3.13 has been in use for over a year now and that hasn't come up so I'm inclined to leave this on this side of the fork for now as the code is slightly simpler.

@gpshead gpshead requested a review from colesbury November 12, 2025 01:40
@gpshead gpshead added needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes type-bug An unexpected behavior, bug, or error labels Nov 12, 2025
Copy link
Contributor

@colesbury colesbury left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@gpshead gpshead merged commit 781cc68 into python:main Nov 13, 2025
50 checks passed
@miss-islington-app
Copy link

Thanks @gpshead for the PR 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14.
🐍🍒⛏🤖

@miss-islington-app
Copy link

Sorry, @gpshead, I could not cleanly backport this to 3.14 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 781cc68c3c814e46e6a74c3a6a32e0f9f8f7eb11 3.14

@miss-islington-app
Copy link

Sorry, @gpshead, I could not cleanly backport this to 3.13 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 781cc68c3c814e46e6a74c3a6a32e0f9f8f7eb11 3.13

CuriousLearner added a commit to CuriousLearner/cpython that referenced this pull request Nov 13, 2025
* main: (463 commits)
  pythongh-140601: Add ResourceWarning to iterparse when not closed (pythonGH-140603)
  pythongh-137969: Fix double evaluation of `ForwardRef`s which rely on globals (python#140974)
  pythongh-139109: A new tracing JIT compiler frontend for CPython (pythonGH-140310)
  pythongh-141004: Document `PyErr_RangedSyntaxLocationObject` (python#141521)
  pythongh-140873: Add support of non-descriptor callables in functools.singledispatchmethod() (pythonGH-140884)
  pythongh-139653: Add PyUnstable_ThreadState_SetStackProtection() (python#139668)
  pythongh-141004: Document `PyCode_Optimize` (pythonGH-141378)
  pythongh-141004: Document C APIs for dictionary keys, values, and items (pythonGH-141009)
  pythongh-137959: Fix `TIER1_TO_TIER2` macro name in JIT InternalDocs (pythonGH-141496)
  pythongh-139871: Add `bytearray.take_bytes([n])` to efficiently extract `bytes` (pythonGH-140128)
  pythongh-140601: Refactor ElementTree.iterparse() tests (pythonGH-141499)
  pythongh-135801: Add the module parameter to compile() etc (pythonGH-139652)
  pythongh-140260: fix data race in `_struct` module initialization with subinterpreters (python#140909)
  pythongh-137109: refactor warning about threads when forking (python#141438)
  pythongh-141004: Document `PyRun_InteractiveOneObject` (pythonGH-141405)
  pythongh-124111: Fix TCL 9 thread detection (pythonGH-128103)
  pythongh-141442: Add escaping to iOS testbed arguments (python#141443)
  pythongh-140936: Fix JIT assertion crash at finalization if some generator is alive (pythonGH-140969)
  Add details about JIT build infrastructure and updating dependencies to `Tools/jit` (python#141167)
  pythongh-141412: Use reliable target URL for urllib example (pythonGH-141428)
  ...
CuriousLearner added a commit to CuriousLearner/cpython that referenced this pull request Nov 14, 2025
* 'main' of github.com:python/cpython: (464 commits)
  pythongh-140601: Add ResourceWarning to iterparse when not closed (pythonGH-140603)
  pythongh-137969: Fix double evaluation of `ForwardRef`s which rely on globals (python#140974)
  pythongh-139109: A new tracing JIT compiler frontend for CPython (pythonGH-140310)
  pythongh-141004: Document `PyErr_RangedSyntaxLocationObject` (python#141521)
  pythongh-140873: Add support of non-descriptor callables in functools.singledispatchmethod() (pythonGH-140884)
  pythongh-139653: Add PyUnstable_ThreadState_SetStackProtection() (python#139668)
  pythongh-141004: Document `PyCode_Optimize` (pythonGH-141378)
  pythongh-141004: Document C APIs for dictionary keys, values, and items (pythonGH-141009)
  pythongh-137959: Fix `TIER1_TO_TIER2` macro name in JIT InternalDocs (pythonGH-141496)
  pythongh-139871: Add `bytearray.take_bytes([n])` to efficiently extract `bytes` (pythonGH-140128)
  pythongh-140601: Refactor ElementTree.iterparse() tests (pythonGH-141499)
  pythongh-135801: Add the module parameter to compile() etc (pythonGH-139652)
  pythongh-140260: fix data race in `_struct` module initialization with subinterpreters (python#140909)
  pythongh-137109: refactor warning about threads when forking (python#141438)
  pythongh-141004: Document `PyRun_InteractiveOneObject` (pythonGH-141405)
  pythongh-124111: Fix TCL 9 thread detection (pythonGH-128103)
  pythongh-141442: Add escaping to iOS testbed arguments (python#141443)
  pythongh-140936: Fix JIT assertion crash at finalization if some generator is alive (pythonGH-140969)
  Add details about JIT build infrastructure and updating dependencies to `Tools/jit` (python#141167)
  pythongh-141412: Use reliable target URL for urllib example (pythonGH-141428)
  ...
CuriousLearner added a commit to CuriousLearner/cpython that referenced this pull request Nov 14, 2025
* 'main' of github.com:python/cpython: (464 commits)
  pythongh-140601: Add ResourceWarning to iterparse when not closed (pythonGH-140603)
  pythongh-137969: Fix double evaluation of `ForwardRef`s which rely on globals (python#140974)
  pythongh-139109: A new tracing JIT compiler frontend for CPython (pythonGH-140310)
  pythongh-141004: Document `PyErr_RangedSyntaxLocationObject` (python#141521)
  pythongh-140873: Add support of non-descriptor callables in functools.singledispatchmethod() (pythonGH-140884)
  pythongh-139653: Add PyUnstable_ThreadState_SetStackProtection() (python#139668)
  pythongh-141004: Document `PyCode_Optimize` (pythonGH-141378)
  pythongh-141004: Document C APIs for dictionary keys, values, and items (pythonGH-141009)
  pythongh-137959: Fix `TIER1_TO_TIER2` macro name in JIT InternalDocs (pythonGH-141496)
  pythongh-139871: Add `bytearray.take_bytes([n])` to efficiently extract `bytes` (pythonGH-140128)
  pythongh-140601: Refactor ElementTree.iterparse() tests (pythonGH-141499)
  pythongh-135801: Add the module parameter to compile() etc (pythonGH-139652)
  pythongh-140260: fix data race in `_struct` module initialization with subinterpreters (python#140909)
  pythongh-137109: refactor warning about threads when forking (python#141438)
  pythongh-141004: Document `PyRun_InteractiveOneObject` (pythonGH-141405)
  pythongh-124111: Fix TCL 9 thread detection (pythonGH-128103)
  pythongh-141442: Add escaping to iOS testbed arguments (python#141443)
  pythongh-140936: Fix JIT assertion crash at finalization if some generator is alive (pythonGH-140969)
  Add details about JIT build infrastructure and updating dependencies to `Tools/jit` (python#141167)
  pythongh-141412: Use reliable target URL for urllib example (pythonGH-141428)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extension-modules C modules in the Modules dir needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes OS-freebsd OS-linux OS-mac OS-netbsd stdlib Standard Library Python modules in the Lib/ directory type-bug An unexpected behavior, bug, or error

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants