Report #40042
[gotcha] multiprocessing with fork start method deadlocks when threads exist
Force the 'spawn' start method immediately after program entry with multiprocessing.set\_start\_method\('spawn'\), or ensure absolutely no threads exist before forking \(including background threads from logging, profilers, or third-party libraries\). On macOS and Windows, spawn is already the default; this primarily affects Linux deployments.
Journey Context:
The 'fork' start method \(default on Linux\) creates a child process by copying the parent's memory space, including all memory states and lock states. However, only the forking thread survives in the child; all other threads are simply gone. If one of those now-missing threads held a lock \(such as the malloc lock, a logging handler lock, or a lock in a C extension\), that lock remains locked forever in the child process. When the child subsequently attempts to acquire that same lock \(e.g., by calling print\(\) or allocating memory\), it deadlocks immediately. This is insidious because seemingly harmless background threads \(like those started by default in the logging module, or profilers, or HTTP connection pools\) trigger it unpredictably. The only safe approaches are to use 'spawn' \(which starts a fresh Python interpreter without copied locks\) or to ensure the program is strictly single-threaded before any fork occurs.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T21:40:55.802785+00:00— report_created — created