Watch at EaseHistorias. Respuestas. Perspectiva.

Tecnología · GUÍA PRÁCTICA

¿Python avisa “resource_tracker: leaked semaphore objects”? Encuentra al propietario antes de ocultarlo

La advertencia final es un síntoma de limpieza, no la causa. Conserva la primera excepción y demuestra propietario, close, join y unlink de cada recurso.

Original technical diagram tracing a Python resource-tracker shutdown warning back through the first failure, resource owner, and normal cleanup path.
Ilustración original: vuelve de la advertencia al primer fallo y al propietario. Watch at Ease

El resource tracker avisa durante el cierre si aún conserva nombres registrados. No identifica qué biblioteca los creó ni demuestra que la última línea sea la causa. Un hijo muerto por señal, un initializer fallido, un pool sin cerrar, una queue o un doble unlink pueden producir lo mismo.

Empieza por la primera excepción y un inventario de propietarios. Registra versión y método de inicio, reduce a un constructor por vez, demuestra cada salida y la secuencia close, shutdown, join y unlink antes de considerar un filtro.

Conserva el primer fallo

Guarda stderr y exit status y busca antes del tracker el primer traceback, señal, initializer failure, timeout, cancelación o terminación forzada.

Registra build de Python, SO, start method, PID, versiones y clase de salida. No empieces filtrando UserWarning.

Asigna constructor y propietario

Busca Pool, Process, Queue, Lock, Semaphore, ProcessPoolExecutor, SharedMemory, joblib y workers. Asigna proceso creador y scope de cleanup.

Usa main guard donde spawn lo requiera, sin tratarlo como cura universal para recursos creados al importar o initializers fallidos.

Demuestra primero la salida normal

Usa context managers o cierra y join el Pool, shutdown del executor, close de queues y feeder-thread join cuando corresponda. SharedMemory tiene un solo owner de unlink.

Evita terminate, kill, os._exit, parada brusca del contenedor y timeout en la línea base. La terminación forzada puede dejar recursos compartidos.

Separa leak real de bookkeeping

Reduce a un constructor y un child y registra create, exit, close, join, unlink y shutdown. Reincorpora una capa de biblioteca cada vez.

En Linux /dev/shm es evidencia auxiliar, no una lista para borrar. No elimines un nombre sin unirlo al proceso detenido y al owner de limpieza.

Prueba versión soportada y carreras

Con lifecycle correcto, prueba un minimal reproducer en el patch soportado actual. Initializer failure, cleanup reentrante y doble unlink pueden causar avisos parecidos.

No pegues unregister privado en producción: demuestra primero double cleanup, missing cleanup o bug de versión.

Cierra con una prueba sin advertencia

Exige salida conocida de cada child, close/join del parent, un solo unlink owner y shutdown sin nueva advertencia; repite bajo el service manager o cancelación CI original.

Si filtras un aviso harmless de tercero, documenta versión, reproducer, upstream issue y condición de retirada.

Original decision diagram separating normal Python shutdown, an exception, a killed child, and double cleanup or a version bug.
Ilustración original: clasifica la salida antes de reparar. Watch at Ease