Technology · PRACTICAL GUIDE
Python resource_tracker leaked shared_memory: assign one lifecycle owner
Map every creator, attacher and tracker family before changing track. Make one process own unlink, then test both survival and cleanup.

A resource_tracker warning does not prove that one line forgot close(). It can also mean two independent Python process families both believe they own the same POSIX shared-memory name, so the first tracker to exit unlinks a segment another process still needs.
The repair is an ownership decision. Record Python version, platform, launch ancestry, creator, attachers and shutdown order; assign exactly one unlink authority; then choose track=True or track=False for each process only after the map is complete.
Freeze the process topology
Record OS, Python version, start method, service manager, creator PID, each attacher PID, how each process was launched, and planned exit order. Treat separate terminals, subprocess trees, containers and uWSGI workers as potentially separate tracker families until proven otherwise.
Capture the exact shared-memory name, create flag, track value and every close or unlink call. Preserve the original warning text and whether later attach attempts fail; do not convert an old warning into a claim about current Python behavior.
Separate handle, mapping and name lifetime
close() ends this Python object’s access. On POSIX, unlink() removes the name; existing mappings and the object’s final reclamation follow platform rules. A clean local close therefore does not prove the shared name remains attachable or that cleanup has an owner.
Assign one row per shared-memory name with creator, active attachers, tracker family, durable owner, close responsibility and one unlink responsibility. More than one unlink owner is a conflict, while no owner is a real leak risk.
Choose the owner model before track
For one multiprocessing family, the shared tracker can own abnormal-exit cleanup while the application still closes every handle and designates one normal unlink path. Do not make every worker unlink a shared segment.
For independently launched or cross-language processes, choose a durable coordinator that outlives its consumers. On Python 3.13+, non-owning independent attachers can use track=False only when that coordinator or another explicit system already owns cleanup.
Keep version and platform branches explicit
Python versions before 3.13 do not expose SharedMemory(track=...). Do not copy private resource_tracker unregister or monkey-patch snippets into production as a generic fix; upgrade, consolidate the process family, or place cleanup behind an explicit coordinator with tested rollback.
On Windows, track is ignored and the OS removes the block when all handles close. On POSIX, named objects can persist until unlink and final unmap. A cross-platform service needs separate acceptance expectations, not one warning-suppression recipe.
Run a two-sided shutdown test
Start the owner, attach two non-owners, write a generation marker, then stop one non-owner. A fresh attacher must still open the same name and read the marker; otherwise cleanup happened too early.
Stop the remaining non-owner and finally the designated owner. After the owner performs the one planned unlink, a new attach must fail and the expected POSIX name must be absent. Repeat abnormal termination in a disposable fixture and record warnings separately from data-lifetime results.
