テクノロジー · 実用ガイド

Python の「resource_tracker: leaked semaphore objects」警告?隠す前に所有者を特定する

終了時の警告は cleanup の症状であって根本原因ではありません。最初の例外を保存し、各 process の semaphore 所有者と close、join、unlink の順序を証明します。

Original technical diagram tracing a Python resource-tracker shutdown warning back through the first failure, resource owner, and normal cleanup path.
オリジナルイラスト:最後の警告から最初の failure と owner に戻ります。 Watch at Ease

resource tracker は interpreter shutdown 時に登録名が残っていると警告します。どの library が作成したかや、最後の行が根本原因かは示しません。signal で kill された child、initializer failure、未終了 Pool、Queue、二重 unlink が同じ警告を生みます。

最初の exception と owner inventory から始めます。Python build、start method、各 constructor、child exit、parent の close、shutdown、join、unlink を記録し、lifecycle が正しいと証明してから suppression を検討します。

最初の failure を保存する

stderr と exit status を保存し、resource-tracker 行より前の traceback、signal、initializer failure、timeout、cancel、forced termination を探します。

Python build、OS、start method、parent/child PID、library version と exit class を記録し、最初から UserWarning を filter しません。

constructor と owner を一覧化する

Pool、Process、Queue、Lock、Semaphore、ProcessPoolExecutor、SharedMemory、joblib、data-loader worker の constructor を探し、作成 process と cleanup scope を割り当てます。

必要な platform では main guard を使いますが、import-time resource や initializer failure まで直る万能策とは考えません。

normal exit を先に証明する

context manager を使い、または Pool を close して join、executor を shutdown、Queue を close し必要なら feeder thread を join します。SharedMemory は合意した一人が一度だけ unlink します。

baseline では terminate、kill、os._exit、container stop、test timeout を避けます。forced termination は shared resource を残せます。

real leak と tracker bookkeeping を分離する

一つの constructor と child に縮小し、create、child exit、close、join、unlink、shutdown の順序を log にします。警告が消えたら一層ずつ戻します。

Linux の /dev/shm は補助 evidence にすぎず deletion list ではありません。停止済み owner と結び付かない name は削除しません。

supported version と race を試す

lifecycle が正しければ current supported patch で minimal reproducer を試します。initializer failure、reentrant cleanup、double unlink race は類似警告の原因になり得ます。

private unregister を貼って静かにせず、double cleanup、missing cleanup、version bug のどれかを証明します。

warning なしの closure test を行う

全 child の exit、parent の close/join、単一 unlink owner、warning のない shutdown を確認し、元の service manager または CI cancel path でも再試験します。

既知の harmless third-party warning を狭く filter する場合も、version、reproducer、upstream issue、remove condition を記録します。

Original decision diagram separating normal Python shutdown, an exception, a killed child, and double cleanup or a version bug.
オリジナルイラスト:exit class ごとに cleanup を選びます。 Watch at Ease